From 8d6910b78e13fad09e82152d18a814b9298f3cf1 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 20 Jun 2020 19:27:36 +0200 Subject: [PATCH] Kernel: Use map_typed() in HPET code and add a register access helper --- Kernel/Time/HPET.cpp | 114 ++++++++++++++++++++----------------------- Kernel/Time/HPET.h | 7 ++- 2 files changed, 59 insertions(+), 62 deletions(-) diff --git a/Kernel/Time/HPET.cpp b/Kernel/Time/HPET.cpp index 2413a9901de..b0295072cde 100644 --- a/Kernel/Time/HPET.cpp +++ b/Kernel/Time/HPET.cpp @@ -31,6 +31,7 @@ #include #include #include +#include namespace Kernel { @@ -123,8 +124,7 @@ bool HPET::test_and_initialize() return false; klog() << "HPET @ " << hpet; - auto region = MM.allocate_kernel_region(hpet.page_base(), (PAGE_SIZE * 2), "HPET Initialization", Region::Access::Read); - auto* sdt = (ACPI::Structures::HPET*)region->vaddr().offset(hpet.offset_in_page()).as_ptr(); + auto sdt = map_typed(hpet); // Note: HPET is only usable from System Memory ASSERT(sdt->event_timer_block.address_space == (u8)ACPI::GenericAddressStructure::AddressSpace::SystemMemory); @@ -144,14 +144,10 @@ bool HPET::check_for_exisiting_periodic_timers() auto hpet = ACPI::Parser::the()->find_table("HPET"); if (hpet.is_null()) return false; - auto region = MM.allocate_kernel_region(hpet.page_base(), (PAGE_SIZE * 2), "HPET Initialization", Region::Access::Read); - auto* sdt = (ACPI::Structures::HPET*)region->vaddr().offset(hpet.offset_in_page()).as_ptr(); + auto sdt = map_typed(hpet); ASSERT(sdt->event_timer_block.address_space == 0); - - auto p_block = PhysicalAddress(sdt->event_timer_block.address); - auto block_region = MM.allocate_kernel_region(p_block, (PAGE_SIZE * 2), "HPET Initialization", Region::Access::Read); - auto* registers = (volatile HPETRegistersBlock*)block_region->vaddr().offset(p_block.offset_in_page()).as_ptr(); + auto registers = map_typed(PhysicalAddress(sdt->event_timer_block.address)); size_t timers_count = ((registers->raw_capabilites.reg >> 8) & 0x1f) + 1; for (size_t index = 0; index < timers_count; index++) { @@ -163,13 +159,11 @@ bool HPET::check_for_exisiting_periodic_timers() void HPET::global_disable() { - auto* registers_block = (volatile HPETRegistersBlock*)m_hpet_mmio_region->vaddr().offset(m_physical_acpi_hpet_registers.offset_in_page()).as_ptr(); - registers_block->configuration.reg = registers_block->configuration.reg & ~(u32)HPETFlags::Configuration::Enable; + registers().configuration.reg = registers().configuration.reg & ~(u32)HPETFlags::Configuration::Enable; } void HPET::global_enable() { - auto* registers_block = (volatile HPETRegistersBlock*)m_hpet_mmio_region->vaddr().offset(m_physical_acpi_hpet_registers.offset_in_page()).as_ptr(); - registers_block->configuration.reg = registers_block->configuration.reg | (u32)HPETFlags::Configuration::Enable; + registers().configuration.reg = registers().configuration.reg | (u32)HPETFlags::Configuration::Enable; } void HPET::set_periodic_comparator_value(const HPETComparator& comparator, u64 value) @@ -177,10 +171,9 @@ void HPET::set_periodic_comparator_value(const HPETComparator& comparator, u64 v disable(comparator); ASSERT(comparator.is_periodic()); ASSERT(comparator.comparator_number() <= m_comparators.size()); - auto* registers_block = (volatile HPETRegistersBlock*)m_hpet_mmio_region->vaddr().offset(m_physical_acpi_hpet_registers.offset_in_page()).as_ptr(); - volatile auto* timer = ®isters_block->timers[comparator.comparator_number()]; - timer->configuration_and_capability = timer->configuration_and_capability | (u32)HPETFlags::TimerConfiguration::ValueSet; - timer->comparator_value = value; + volatile auto& timer = registers().timers[comparator.comparator_number()]; + timer.configuration_and_capability = timer.configuration_and_capability | (u32)HPETFlags::TimerConfiguration::ValueSet; + timer.comparator_value = value; enable(comparator); } @@ -189,9 +182,9 @@ void HPET::set_non_periodic_comparator_value(const HPETComparator& comparator, u ASSERT_INTERRUPTS_DISABLED(); ASSERT(!comparator.is_periodic()); ASSERT(comparator.comparator_number() <= m_comparators.size()); - auto* registers_block = (volatile HPETRegistersBlock*)m_hpet_mmio_region->vaddr().offset(m_physical_acpi_hpet_registers.offset_in_page()).as_ptr(); - registers_block->timers[comparator.comparator_number()].comparator_value = main_counter_value() + value; + registers().timers[comparator.comparator_number()].comparator_value = main_counter_value() + value; } + void HPET::enable_periodic_interrupt(const HPETComparator& comparator) { #ifdef HPET_DEBUG @@ -199,11 +192,10 @@ void HPET::enable_periodic_interrupt(const HPETComparator& comparator) #endif disable(comparator); ASSERT(comparator.comparator_number() <= m_comparators.size()); - auto* registers_block = (volatile HPETRegistersBlock*)m_hpet_mmio_region->vaddr().offset(m_physical_acpi_hpet_registers.offset_in_page()).as_ptr(); - volatile auto* timer = ®isters_block->timers[comparator.comparator_number()]; - auto configuration_and_capability = timer->configuration_and_capability; + volatile auto& timer = registers().timers[comparator.comparator_number()]; + auto configuration_and_capability = timer.configuration_and_capability; ASSERT(configuration_and_capability & (u32)HPETFlags::TimerConfiguration::PeriodicInterruptCapable); - timer->configuration_and_capability = configuration_and_capability | (u32)HPETFlags::TimerConfiguration::TimerType; + timer.configuration_and_capability = configuration_and_capability | (u32)HPETFlags::TimerConfiguration::TimerType; enable(comparator); } void HPET::disable_periodic_interrupt(const HPETComparator& comparator) @@ -213,11 +205,10 @@ void HPET::disable_periodic_interrupt(const HPETComparator& comparator) #endif disable(comparator); ASSERT(comparator.comparator_number() <= m_comparators.size()); - auto* registers_block = (volatile HPETRegistersBlock*)m_hpet_mmio_region->vaddr().offset(m_physical_acpi_hpet_registers.offset_in_page()).as_ptr(); - auto volatile* timer = ®isters_block->timers[comparator.comparator_number()]; - auto configuration_and_capability = timer->configuration_and_capability; + auto volatile& timer = registers().timers[comparator.comparator_number()]; + auto configuration_and_capability = timer.configuration_and_capability; ASSERT(configuration_and_capability & (u32)HPETFlags::TimerConfiguration::PeriodicInterruptCapable); - timer->configuration_and_capability = configuration_and_capability & ~(u32)HPETFlags::TimerConfiguration::TimerType; + timer.configuration_and_capability = configuration_and_capability & ~(u32)HPETFlags::TimerConfiguration::TimerType; enable(comparator); } @@ -227,9 +218,8 @@ void HPET::disable(const HPETComparator& comparator) klog() << "HPET: Disable comparator " << comparator.comparator_number() << "."; #endif ASSERT(comparator.comparator_number() <= m_comparators.size()); - auto* registers_block = (volatile HPETRegistersBlock*)m_hpet_mmio_region->vaddr().offset(m_physical_acpi_hpet_registers.offset_in_page()).as_ptr(); - volatile auto* timer = ®isters_block->timers[comparator.comparator_number()]; - timer->configuration_and_capability = timer->configuration_and_capability & ~(u32)HPETFlags::TimerConfiguration::InterruptEnable; + volatile auto& timer = registers().timers[comparator.comparator_number()]; + timer.configuration_and_capability = timer.configuration_and_capability & ~(u32)HPETFlags::TimerConfiguration::InterruptEnable; } void HPET::enable(const HPETComparator& comparator) { @@ -237,16 +227,15 @@ void HPET::enable(const HPETComparator& comparator) klog() << "HPET: Enable comparator " << comparator.comparator_number() << "."; #endif ASSERT(comparator.comparator_number() <= m_comparators.size()); - auto* registers_block = (volatile HPETRegistersBlock*)m_hpet_mmio_region->vaddr().offset(m_physical_acpi_hpet_registers.offset_in_page()).as_ptr(); - volatile auto* timer = ®isters_block->timers[comparator.comparator_number()]; - timer->configuration_and_capability = timer->configuration_and_capability | (u32)HPETFlags::TimerConfiguration::InterruptEnable; + volatile auto& timer = registers().timers[comparator.comparator_number()]; + timer.configuration_and_capability = timer.configuration_and_capability | (u32)HPETFlags::TimerConfiguration::InterruptEnable; } u64 HPET::main_counter_value() const { - auto* registers_block = (const volatile HPETRegistersBlock*)m_hpet_mmio_region->vaddr().offset(m_physical_acpi_hpet_registers.offset_in_page()).as_ptr(); - return registers_block->main_counter_value.reg; + return registers().main_counter_value.reg; } + u64 HPET::frequency() const { return m_frequency; @@ -256,9 +245,8 @@ Vector HPET::capable_interrupt_numbers(const HPETComparator& comparato { ASSERT(comparator.comparator_number() <= m_comparators.size()); Vector capable_interrupts; - auto* registers_block = (volatile HPETRegistersBlock*)m_hpet_mmio_region->vaddr().offset(m_physical_acpi_hpet_registers.offset_in_page()).as_ptr(); - auto* comparator_registers = (const volatile TimerStructure*)®isters_block->timers[comparator.comparator_number()]; - u32 interrupt_bitfield = comparator_registers->configuration_and_capability >> 32; + auto& comparator_registers = (const volatile TimerStructure&)registers().timers[comparator.comparator_number()]; + u32 interrupt_bitfield = comparator_registers.configuration_and_capability >> 32; for (size_t index = 0; index < 32; index++) { if (interrupt_bitfield & 1) capable_interrupts.append(index); @@ -271,9 +259,8 @@ Vector HPET::capable_interrupt_numbers(u8 comparator_number) { ASSERT(comparator_number <= m_comparators.size()); Vector capable_interrupts; - auto* registers_block = (volatile HPETRegistersBlock*)m_hpet_mmio_region->vaddr().offset(m_physical_acpi_hpet_registers.offset_in_page()).as_ptr(); - auto* comparator_registers = (const volatile TimerStructure*)®isters_block->timers[comparator_number]; - u32 interrupt_bitfield = comparator_registers->configuration_and_capability >> 32; + auto& comparator_registers = (const volatile TimerStructure&)registers().timers[comparator_number]; + u32 interrupt_bitfield = comparator_registers.configuration_and_capability >> 32; for (size_t index = 0; index < 32; index++) { if (interrupt_bitfield & 1) capable_interrupts.append(index); @@ -285,17 +272,15 @@ Vector HPET::capable_interrupt_numbers(u8 comparator_number) void HPET::set_comparator_irq_vector(u8 comparator_number, u8 irq_vector) { ASSERT(comparator_number <= m_comparators.size()); - auto* registers_block = (volatile HPETRegistersBlock*)m_hpet_mmio_region->vaddr().offset(m_physical_acpi_hpet_registers.offset_in_page()).as_ptr(); - auto* comparator_registers = (volatile TimerStructure*)®isters_block->timers[comparator_number]; - comparator_registers->configuration_and_capability = comparator_registers->configuration_and_capability | (irq_vector << 9); + auto& comparator_registers = (volatile TimerStructure&)registers().timers[comparator_number]; + comparator_registers.configuration_and_capability = comparator_registers.configuration_and_capability | (irq_vector << 9); } bool HPET::is_periodic_capable(u8 comparator_number) const { ASSERT(comparator_number <= m_comparators.size()); - auto* registers_block = (volatile HPETRegistersBlock*)m_hpet_mmio_region->vaddr().offset(m_physical_acpi_hpet_registers.offset_in_page()).as_ptr(); - auto* comparator_registers = (const volatile TimerStructure*)®isters_block->timers[comparator_number]; - return comparator_registers->configuration_and_capability & (u32)HPETFlags::TimerConfiguration::PeriodicInterruptCapable; + auto& comparator_registers = (const volatile TimerStructure&)registers().timers[comparator_number]; + return comparator_registers.configuration_and_capability & (u32)HPETFlags::TimerConfiguration::PeriodicInterruptCapable; } void HPET::set_comparators_to_optimal_interrupt_state(size_t) @@ -304,36 +289,43 @@ void HPET::set_comparators_to_optimal_interrupt_state(size_t) ASSERT_NOT_REACHED(); } -PhysicalAddress HPET::find_acpi_hept_registers_block() +PhysicalAddress HPET::find_acpi_hpet_registers_block() { - auto region = MM.allocate_kernel_region(m_physical_acpi_hpet_table.page_base(), (PAGE_SIZE * 2), "HPET Initialization", Region::Access::Read); - auto* sdt = (const volatile ACPI::Structures::HPET*)region->vaddr().offset(m_physical_acpi_hpet_table.offset_in_page()).as_ptr(); + auto sdt = map_typed(m_physical_acpi_hpet_table); ASSERT(sdt->event_timer_block.address_space == (u8)ACPI::GenericAddressStructure::AddressSpace::SystemMemory); return PhysicalAddress(sdt->event_timer_block.address); } + +const volatile HPETRegistersBlock& HPET::registers() const +{ + return *(const volatile HPETRegistersBlock*)m_hpet_mmio_region->vaddr().offset(m_physical_acpi_hpet_registers.offset_in_page()).as_ptr(); +} + +volatile HPETRegistersBlock& HPET::registers() +{ + return *(volatile HPETRegistersBlock*)m_hpet_mmio_region->vaddr().offset(m_physical_acpi_hpet_registers.offset_in_page()).as_ptr(); +} + u64 HPET::calculate_ticks_in_nanoseconds() const { - auto* registers_block = (const volatile HPETRegistersBlock*)m_hpet_mmio_region->vaddr().offset(m_physical_acpi_hpet_registers.offset_in_page()).as_ptr(); - return ABSOLUTE_MAXIMUM_COUNTER_TICK_PERIOD / registers_block->capabilities.main_counter_tick_period; + return ABSOLUTE_MAXIMUM_COUNTER_TICK_PERIOD / registers().capabilities.main_counter_tick_period; } + HPET::HPET(PhysicalAddress acpi_hpet) : m_physical_acpi_hpet_table(acpi_hpet) - , m_physical_acpi_hpet_registers(find_acpi_hept_registers_block()) + , m_physical_acpi_hpet_registers(find_acpi_hpet_registers_block()) , m_hpet_mmio_region(MM.allocate_kernel_region(m_physical_acpi_hpet_registers.page_base(), PAGE_SIZE, "HPET MMIO", Region::Access::Read | Region::Access::Write)) { - auto region = MM.allocate_kernel_region(m_physical_acpi_hpet_table.page_base(), (PAGE_SIZE * 2), "HPET Initialization", Region::Access::Read); - auto* sdt = (const volatile ACPI::Structures::HPET*)region->vaddr().offset(m_physical_acpi_hpet_table.offset_in_page()).as_ptr(); + auto sdt = map_typed(m_physical_acpi_hpet_table); m_vendor_id = sdt->pci_vendor_id; m_minimum_tick = sdt->mininum_clock_tick; klog() << "HPET: Minimum clock tick - " << m_minimum_tick; - auto* registers_block = (volatile HPETRegistersBlock*)m_hpet_mmio_region->vaddr().offset(m_physical_acpi_hpet_registers.offset_in_page()).as_ptr(); - // Note: We must do a 32 bit access to offsets 0x0, or 0x4 only. - size_t timers_count = ((registers_block->raw_capabilites.reg >> 8) & 0x1f) + 1; + size_t timers_count = ((registers().raw_capabilites.reg >> 8) & 0x1f) + 1; klog() << "HPET: Timers count - " << timers_count; ASSERT(timers_count >= 2); - auto* capabilities_register = (const volatile HPETCapabilityRegister*)®isters_block->raw_capabilites.reg; + auto* capabilities_register = (const volatile HPETCapabilityRegister*)®isters().raw_capabilites.reg; global_disable(); @@ -342,9 +334,9 @@ HPET::HPET(PhysicalAddress acpi_hpet) ASSERT(capabilities_register->main_counter_tick_period <= ABSOLUTE_MAXIMUM_COUNTER_TICK_PERIOD); // Reset the counter, just in case... - registers_block->main_counter_value.reg = 0; - if (registers_block->raw_capabilites.reg & (u32)HPETFlags::Attributes::LegacyReplacementRouteCapable) - registers_block->configuration.reg = registers_block->configuration.reg | (u32)HPETFlags::Configuration::LegacyReplacementRoute; + registers().main_counter_value.reg = 0; + if (registers().raw_capabilites.reg & (u32)HPETFlags::Attributes::LegacyReplacementRouteCapable) + registers().configuration.reg = registers().configuration.reg | (u32)HPETFlags::Configuration::LegacyReplacementRoute; m_comparators.append(HPETComparator::create(0, 0, is_periodic_capable(0))); m_comparators.append(HPETComparator::create(1, 8, is_periodic_capable(1))); diff --git a/Kernel/Time/HPET.h b/Kernel/Time/HPET.h index 5fec10feb8e..d43fb7504d6 100644 --- a/Kernel/Time/HPET.h +++ b/Kernel/Time/HPET.h @@ -37,6 +37,8 @@ namespace Kernel { class HPETComparator; +struct HPETRegistersBlock; + class HPET { public: static bool initialized(); @@ -63,6 +65,9 @@ public: Vector capable_interrupt_numbers(const HPETComparator&); private: + const volatile HPETRegistersBlock& registers() const; + volatile HPETRegistersBlock& registers(); + void global_disable(); void global_enable(); @@ -71,7 +76,7 @@ private: u64 calculate_ticks_in_nanoseconds() const; - PhysicalAddress find_acpi_hept_registers_block(); + PhysicalAddress find_acpi_hpet_registers_block(); explicit HPET(PhysicalAddress acpi_hpet); PhysicalAddress m_physical_acpi_hpet_table; PhysicalAddress m_physical_acpi_hpet_registers;