mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 21:27:34 +00:00
Revert "Kernel: Fix HPET timer structure layout"
This reverts commit af22204488
.
According to the HPET specification, each theoretical comparator takes
32 bytes in the MMIO space.
Although I hardly believe that any system will implement all 32
comparators, in practice if a machine happens to have more than 3
comparators, we need to address the comparators correctly if we want to
use them.
This commit is contained in:
parent
4ae3bfa40d
commit
bbe1d7e239
2 changed files with 18 additions and 33 deletions
|
@ -74,10 +74,6 @@ struct [[gnu::packed]] TimerStructure {
|
||||||
volatile u32 interrupt_routing;
|
volatile u32 interrupt_routing;
|
||||||
HPETRegister comparator_value;
|
HPETRegister comparator_value;
|
||||||
volatile u64 fsb_interrupt_route;
|
volatile u64 fsb_interrupt_route;
|
||||||
};
|
|
||||||
|
|
||||||
struct [[gnu::packed]] TimerStructureWithReserved {
|
|
||||||
TimerStructure timer;
|
|
||||||
u64 reserved;
|
u64 reserved;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -96,24 +92,13 @@ struct [[gnu::packed]] HPETRegistersBlock {
|
||||||
u8 reserved2[0xF0 - 0x28];
|
u8 reserved2[0xF0 - 0x28];
|
||||||
HPETRegister main_counter_value;
|
HPETRegister main_counter_value;
|
||||||
u64 reserved3;
|
u64 reserved3;
|
||||||
TimerStructureWithReserved timers[3];
|
TimerStructure timers[3];
|
||||||
TimerStructure timers2[29];
|
u8 reserved4[0x400 - 0x160];
|
||||||
|
|
||||||
ALWAYS_INLINE TimerStructure& get_timer_by_index(unsigned index)
|
|
||||||
{
|
|
||||||
VERIFY(index < 32);
|
|
||||||
if (index < 3)
|
|
||||||
return timers[index].timer;
|
|
||||||
return timers2[index - 3];
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(TimerStructure) == 0x18);
|
|
||||||
static_assert(sizeof(TimerStructureWithReserved) == 0x20);
|
|
||||||
static_assert(__builtin_offsetof(HPETRegistersBlock, main_counter_value) == 0xf0);
|
static_assert(__builtin_offsetof(HPETRegistersBlock, main_counter_value) == 0xf0);
|
||||||
static_assert(__builtin_offsetof(HPETRegistersBlock, timers[0]) == 0x100);
|
static_assert(__builtin_offsetof(HPETRegistersBlock, timers[0]) == 0x100);
|
||||||
static_assert(__builtin_offsetof(HPETRegistersBlock, timers[1]) == 0x120);
|
static_assert(__builtin_offsetof(HPETRegistersBlock, timers[1]) == 0x120);
|
||||||
static_assert(sizeof(HPETRegistersBlock) == 0x418);
|
|
||||||
|
|
||||||
static u64 read_register_safe64(const HPETRegister& reg)
|
static u64 read_register_safe64(const HPETRegister& reg)
|
||||||
{
|
{
|
||||||
|
@ -181,7 +166,7 @@ UNMAP_AFTER_INIT bool HPET::check_for_exisiting_periodic_timers()
|
||||||
|
|
||||||
size_t timers_count = ((registers->capabilities.attributes >> 8) & 0x1f) + 1;
|
size_t timers_count = ((registers->capabilities.attributes >> 8) & 0x1f) + 1;
|
||||||
for (size_t index = 0; index < timers_count; index++) {
|
for (size_t index = 0; index < timers_count; index++) {
|
||||||
if (registers->get_timer_by_index(index).capabilities & (u32)HPETFlags::TimerConfiguration::PeriodicInterruptCapable)
|
if (registers->timers[index].capabilities & (u32)HPETFlags::TimerConfiguration::PeriodicInterruptCapable)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -212,7 +197,7 @@ void HPET::update_periodic_comparator_value()
|
||||||
regs.main_counter_value.low = 0;
|
regs.main_counter_value.low = 0;
|
||||||
regs.main_counter_value.high = 0;
|
regs.main_counter_value.high = 0;
|
||||||
for (auto& comparator : m_comparators) {
|
for (auto& comparator : m_comparators) {
|
||||||
auto& timer = regs.get_timer_by_index(comparator.comparator_number());
|
auto& timer = regs.timers[comparator.comparator_number()];
|
||||||
if (!comparator.is_enabled())
|
if (!comparator.is_enabled())
|
||||||
continue;
|
continue;
|
||||||
if (comparator.is_periodic()) {
|
if (comparator.is_periodic()) {
|
||||||
|
@ -250,7 +235,8 @@ void HPET::update_non_periodic_comparator_value(const HPETComparator& comparator
|
||||||
VERIFY_INTERRUPTS_DISABLED();
|
VERIFY_INTERRUPTS_DISABLED();
|
||||||
VERIFY(!comparator.is_periodic());
|
VERIFY(!comparator.is_periodic());
|
||||||
VERIFY(comparator.comparator_number() <= m_comparators.size());
|
VERIFY(comparator.comparator_number() <= m_comparators.size());
|
||||||
auto& timer = registers().get_timer_by_index(comparator.comparator_number());
|
auto& regs = registers();
|
||||||
|
auto& timer = regs.timers[comparator.comparator_number()];
|
||||||
u64 value = frequency() / comparator.ticks_per_second();
|
u64 value = frequency() / comparator.ticks_per_second();
|
||||||
// NOTE: If the main counter passes this new value before we finish writing it, we will never receive an interrupt!
|
// NOTE: If the main counter passes this new value before we finish writing it, we will never receive an interrupt!
|
||||||
u64 new_counter_value = read_main_counter() + value;
|
u64 new_counter_value = read_main_counter() + value;
|
||||||
|
@ -303,7 +289,7 @@ void HPET::enable_periodic_interrupt(const HPETComparator& comparator)
|
||||||
#endif
|
#endif
|
||||||
disable(comparator);
|
disable(comparator);
|
||||||
VERIFY(comparator.comparator_number() <= m_comparators.size());
|
VERIFY(comparator.comparator_number() <= m_comparators.size());
|
||||||
auto& timer = registers().get_timer_by_index(comparator.comparator_number());
|
auto& timer = registers().timers[comparator.comparator_number()];
|
||||||
auto capabilities = timer.capabilities;
|
auto capabilities = timer.capabilities;
|
||||||
VERIFY(capabilities & (u32)HPETFlags::TimerConfiguration::PeriodicInterruptCapable);
|
VERIFY(capabilities & (u32)HPETFlags::TimerConfiguration::PeriodicInterruptCapable);
|
||||||
timer.capabilities = capabilities | (u32)HPETFlags::TimerConfiguration::GeneratePeriodicInterrupt;
|
timer.capabilities = capabilities | (u32)HPETFlags::TimerConfiguration::GeneratePeriodicInterrupt;
|
||||||
|
@ -317,7 +303,7 @@ void HPET::disable_periodic_interrupt(const HPETComparator& comparator)
|
||||||
#endif
|
#endif
|
||||||
disable(comparator);
|
disable(comparator);
|
||||||
VERIFY(comparator.comparator_number() <= m_comparators.size());
|
VERIFY(comparator.comparator_number() <= m_comparators.size());
|
||||||
auto& timer = registers().get_timer_by_index(comparator.comparator_number());
|
auto& timer = registers().timers[comparator.comparator_number()];
|
||||||
auto capabilities = timer.capabilities;
|
auto capabilities = timer.capabilities;
|
||||||
VERIFY(capabilities & (u32)HPETFlags::TimerConfiguration::PeriodicInterruptCapable);
|
VERIFY(capabilities & (u32)HPETFlags::TimerConfiguration::PeriodicInterruptCapable);
|
||||||
timer.capabilities = capabilities & ~(u32)HPETFlags::TimerConfiguration::GeneratePeriodicInterrupt;
|
timer.capabilities = capabilities & ~(u32)HPETFlags::TimerConfiguration::GeneratePeriodicInterrupt;
|
||||||
|
@ -331,7 +317,7 @@ void HPET::disable(const HPETComparator& comparator)
|
||||||
klog() << "HPET: Disable comparator " << comparator.comparator_number() << ".";
|
klog() << "HPET: Disable comparator " << comparator.comparator_number() << ".";
|
||||||
#endif
|
#endif
|
||||||
VERIFY(comparator.comparator_number() <= m_comparators.size());
|
VERIFY(comparator.comparator_number() <= m_comparators.size());
|
||||||
auto& timer = registers().get_timer_by_index(comparator.comparator_number());
|
auto& timer = registers().timers[comparator.comparator_number()];
|
||||||
timer.capabilities = timer.capabilities & ~(u32)HPETFlags::TimerConfiguration::InterruptEnable;
|
timer.capabilities = timer.capabilities & ~(u32)HPETFlags::TimerConfiguration::InterruptEnable;
|
||||||
}
|
}
|
||||||
void HPET::enable(const HPETComparator& comparator)
|
void HPET::enable(const HPETComparator& comparator)
|
||||||
|
@ -340,7 +326,7 @@ void HPET::enable(const HPETComparator& comparator)
|
||||||
klog() << "HPET: Enable comparator " << comparator.comparator_number() << ".";
|
klog() << "HPET: Enable comparator " << comparator.comparator_number() << ".";
|
||||||
#endif
|
#endif
|
||||||
VERIFY(comparator.comparator_number() <= m_comparators.size());
|
VERIFY(comparator.comparator_number() <= m_comparators.size());
|
||||||
auto& timer = registers().get_timer_by_index(comparator.comparator_number());
|
auto& timer = registers().timers[comparator.comparator_number()];
|
||||||
timer.capabilities = timer.capabilities | (u32)HPETFlags::TimerConfiguration::InterruptEnable;
|
timer.capabilities = timer.capabilities | (u32)HPETFlags::TimerConfiguration::InterruptEnable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,7 +334,7 @@ Vector<unsigned> HPET::capable_interrupt_numbers(const HPETComparator& comparato
|
||||||
{
|
{
|
||||||
VERIFY(comparator.comparator_number() <= m_comparators.size());
|
VERIFY(comparator.comparator_number() <= m_comparators.size());
|
||||||
Vector<unsigned> capable_interrupts;
|
Vector<unsigned> capable_interrupts;
|
||||||
auto& comparator_registers = registers().get_timer_by_index(comparator.comparator_number());
|
auto& comparator_registers = registers().timers[comparator.comparator_number()];
|
||||||
u32 interrupt_bitfield = comparator_registers.interrupt_routing;
|
u32 interrupt_bitfield = comparator_registers.interrupt_routing;
|
||||||
for (size_t index = 0; index < 32; index++) {
|
for (size_t index = 0; index < 32; index++) {
|
||||||
if (interrupt_bitfield & 1)
|
if (interrupt_bitfield & 1)
|
||||||
|
@ -362,7 +348,7 @@ Vector<unsigned> HPET::capable_interrupt_numbers(u8 comparator_number)
|
||||||
{
|
{
|
||||||
VERIFY(comparator_number <= m_comparators.size());
|
VERIFY(comparator_number <= m_comparators.size());
|
||||||
Vector<unsigned> capable_interrupts;
|
Vector<unsigned> capable_interrupts;
|
||||||
auto& comparator_registers = registers().get_timer_by_index(comparator_number);
|
auto& comparator_registers = registers().timers[comparator_number];
|
||||||
u32 interrupt_bitfield = comparator_registers.interrupt_routing;
|
u32 interrupt_bitfield = comparator_registers.interrupt_routing;
|
||||||
for (size_t index = 0; index < 32; index++) {
|
for (size_t index = 0; index < 32; index++) {
|
||||||
if (interrupt_bitfield & 1)
|
if (interrupt_bitfield & 1)
|
||||||
|
@ -375,14 +361,14 @@ Vector<unsigned> HPET::capable_interrupt_numbers(u8 comparator_number)
|
||||||
void HPET::set_comparator_irq_vector(u8 comparator_number, u8 irq_vector)
|
void HPET::set_comparator_irq_vector(u8 comparator_number, u8 irq_vector)
|
||||||
{
|
{
|
||||||
VERIFY(comparator_number <= m_comparators.size());
|
VERIFY(comparator_number <= m_comparators.size());
|
||||||
auto& comparator_registers = registers().get_timer_by_index(comparator_number);
|
auto& comparator_registers = registers().timers[comparator_number];
|
||||||
comparator_registers.capabilities = comparator_registers.capabilities | (irq_vector << 9);
|
comparator_registers.capabilities = comparator_registers.capabilities | (irq_vector << 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HPET::is_periodic_capable(u8 comparator_number)
|
bool HPET::is_periodic_capable(u8 comparator_number) const
|
||||||
{
|
{
|
||||||
VERIFY(comparator_number <= m_comparators.size());
|
VERIFY(comparator_number <= m_comparators.size());
|
||||||
auto& comparator_registers = registers().get_timer_by_index(comparator_number);
|
auto& comparator_registers = registers().timers[comparator_number];
|
||||||
return comparator_registers.capabilities & (u32)HPETFlags::TimerConfiguration::PeriodicInterruptCapable;
|
return comparator_registers.capabilities & (u32)HPETFlags::TimerConfiguration::PeriodicInterruptCapable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,9 +425,8 @@ UNMAP_AFTER_INIT HPET::HPET(PhysicalAddress acpi_hpet)
|
||||||
klog() << "HPET: Timers count - " << timers_count;
|
klog() << "HPET: Timers count - " << timers_count;
|
||||||
klog() << "HPET: Main counter size: " << ((regs.capabilities.attributes & (u32)HPETFlags::Attributes::Counter64BitCapable) ? "64 bit" : "32 bit");
|
klog() << "HPET: Main counter size: " << ((regs.capabilities.attributes & (u32)HPETFlags::Attributes::Counter64BitCapable) ? "64 bit" : "32 bit");
|
||||||
for (size_t i = 0; i < timers_count; i++) {
|
for (size_t i = 0; i < timers_count; i++) {
|
||||||
auto& timer = regs.get_timer_by_index(i);
|
bool capable_64_bit = regs.timers[i].capabilities & (u32)HPETFlags::TimerConfiguration::Timer64BitsCapable;
|
||||||
bool capable_64_bit = timer.capabilities & (u32)HPETFlags::TimerConfiguration::Timer64BitsCapable;
|
klog() << "HPET: Timer[" << i << "] comparator size: " << (capable_64_bit ? "64 bit" : "32 bit") << " mode: " << ((!capable_64_bit || (regs.timers[i].capabilities & (u32)HPETFlags::TimerConfiguration::Force32BitMode)) ? "32 bit" : "64 bit");
|
||||||
klog() << "HPET: Timer[" << i << "] comparator size: " << (capable_64_bit ? "64 bit" : "32 bit") << " mode: " << ((!capable_64_bit || (timer.capabilities & (u32)HPETFlags::TimerConfiguration::Force32BitMode)) ? "32 bit" : "64 bit");
|
|
||||||
}
|
}
|
||||||
VERIFY(timers_count >= 2);
|
VERIFY(timers_count >= 2);
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ private:
|
||||||
void global_disable();
|
void global_disable();
|
||||||
void global_enable();
|
void global_enable();
|
||||||
|
|
||||||
bool is_periodic_capable(u8 comparator_number);
|
bool is_periodic_capable(u8 comparator_number) const;
|
||||||
void set_comparators_to_optimal_interrupt_state(size_t timers_count);
|
void set_comparators_to_optimal_interrupt_state(size_t timers_count);
|
||||||
|
|
||||||
u64 nanoseconds_to_raw_ticks() const;
|
u64 nanoseconds_to_raw_ticks() const;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue