Explorar el Código

Kernel: Use TypedMapping for accessing IOAPIC registers

Andreas Kling hace 5 años
padre
commit
a75c290e51

+ 9 - 10
Kernel/Interrupts/IOAPIC.cpp

@@ -32,6 +32,7 @@
 #include <Kernel/Interrupts/IOAPIC.h>
 #include <Kernel/Interrupts/InterruptManagement.h>
 #include <Kernel/VM/MemoryManager.h>
+#include <Kernel/VM/TypedMapping.h>
 
 #define IOAPIC_REDIRECTION_ENTRY_OFFSET 0x10
 namespace Kernel {
@@ -44,8 +45,8 @@ enum DeliveryMode {
     External = 7
 };
 
-IOAPIC::IOAPIC(ioapic_mmio_regs& regs, u32 gsi_base)
-    : m_physical_access_registers(regs)
+IOAPIC::IOAPIC(PhysicalAddress address, u32 gsi_base)
+    : m_address(address)
     , m_gsi_base(gsi_base)
     , m_id((read_register(0x0) >> 24) & 0xFF)
     , m_version(read_register(0x1) & 0xFF)
@@ -314,10 +315,9 @@ u16 IOAPIC::get_irr() const
 void IOAPIC::write_register(u32 index, u32 value) const
 {
     InterruptDisabler disabler;
-    auto region = MM.allocate_kernel_region(PhysicalAddress(page_base_of(&m_physical_access_registers)), (PAGE_SIZE * 2), "IOAPIC Write", Region::Access::Read | Region::Access::Write);
-    auto& regs = *(volatile ioapic_mmio_regs*)region->vaddr().offset(offset_in_page(&m_physical_access_registers)).as_ptr();
-    regs.select = index;
-    regs.window = value;
+    auto regs = map_typed_writable<ioapic_mmio_regs>(m_address);
+    regs->select = index;
+    regs->window = value;
 #ifdef IOAPIC_DEBUG
     dbg() << "IOAPIC Writing, Value 0x" << String::format("%x", regs.window) << " @ offset 0x" << String::format("%x", regs.select);
 #endif
@@ -325,12 +325,11 @@ void IOAPIC::write_register(u32 index, u32 value) const
 u32 IOAPIC::read_register(u32 index) const
 {
     InterruptDisabler disabler;
-    auto region = MM.allocate_kernel_region(PhysicalAddress(page_base_of(&m_physical_access_registers)), (PAGE_SIZE * 2), "IOAPIC Read", Region::Access::Read | Region::Access::Write);
-    auto& regs = *(volatile ioapic_mmio_regs*)region->vaddr().offset(offset_in_page(&m_physical_access_registers)).as_ptr();
-    regs.select = index;
+    auto regs = map_typed_writable<ioapic_mmio_regs>(m_address);
+    regs->select = index;
 #ifdef IOAPIC_DEBUG
     dbg() << "IOAPIC Reading, Value 0x" << String::format("%x", regs.window) << " @ offset 0x" << String::format("%x", regs.select);
 #endif
-    return regs.window;
+    return regs->window;
 }
 }

+ 2 - 2
Kernel/Interrupts/IOAPIC.h

@@ -59,7 +59,7 @@ private:
 
 class IOAPIC final : public IRQController {
 public:
-    IOAPIC(ioapic_mmio_regs& regs, u32 gsi_base);
+    IOAPIC(PhysicalAddress, u32 gsi_base);
     virtual void enable(const GenericInterruptHandler&) override;
     virtual void disable(const GenericInterruptHandler&) override;
     virtual void hard_disable() override;
@@ -97,7 +97,7 @@ private:
     void map_pci_interrupts();
     void isa_identity_map(int index);
 
-    ioapic_mmio_regs& m_physical_access_registers;
+    PhysicalAddress m_address;
     u32 m_gsi_base;
     u8 m_id;
     u8 m_version;

+ 1 - 1
Kernel/Interrupts/InterruptManagement.cpp

@@ -216,7 +216,7 @@ void InterruptManagement::locate_apic_data()
             dbg() << "IOAPIC found @ MADT entry " << entry_index << ", MMIO Registers @ " << PhysicalAddress(ioapic_entry->ioapic_address);
             m_interrupt_controllers.resize(1 + irq_controller_count);
             // FIXME: Casting ioapic_entry->ioapic_address below looks suspicious!
-            m_interrupt_controllers[irq_controller_count] = adopt(*new IOAPIC(*(ioapic_mmio_regs*)(FlatPtr)ioapic_entry->ioapic_address, ioapic_entry->gsi_base));
+            m_interrupt_controllers[irq_controller_count] = adopt(*new IOAPIC(PhysicalAddress(ioapic_entry->ioapic_address), ioapic_entry->gsi_base));
             irq_controller_count++;
         }
         if (madt_entry->type == (u8)ACPI::Structures::MADTEntryType::InterruptSourceOverride) {