diff --git a/arch/ioapic.cc b/arch/ioapic.cc index 28606bb..c610c01 100644 --- a/arch/ioapic.cc +++ b/arch/ioapic.cc @@ -1,4 +1,6 @@ #include "ioapic.h" +#include "apic.h" +#include "core.h" namespace IOAPIC { /*! \brief IOAPIC registers memory mapped into the CPU's address space. @@ -20,10 +22,42 @@ volatile Register *IOWIN_REG = // IOAPIC manual, p. 8 const Index IOAPICID_IDX = 0x00; const Index IOREDTBL_IDX = 0x10; +const Index IOREDTBL_ENTRY_SIZE = 0x02; const uint8_t slot_max = 24; -void init() {} +RedirectionTableEntry readEntry(Index slot) { + *IOREGSEL_REG = IOREDTBL_IDX + slot * IOREDTBL_ENTRY_SIZE; + Register low = *IOWIN_REG; + *IOREGSEL_REG += IOREDTBL_ENTRY_SIZE / 2; + Register high = *IOWIN_REG; + return RedirectionTableEntry{low, high}; +} + +void writeEntry(Index slot, RedirectionTableEntry entry) { + *IOREGSEL_REG = IOREDTBL_IDX + slot * IOREDTBL_ENTRY_SIZE; + *IOWIN_REG = entry.value_low; + *IOREGSEL_REG += IOREDTBL_ENTRY_SIZE / 2; + *IOWIN_REG = entry.value_high; +} + +void init() { + for (uint8_t slot = 0; slot < slot_max; slot++) { + RedirectionTableEntry entry = readEntry(slot); + entry.destination = (1 << Core::count()) - 1; + entry.interrupt_mask = MASKED; + entry.trigger_mode = EDGE; + entry.polarity = HIGH; + entry.destination_mode = LOGICAL; + entry.delivery_mode = LOWEST_PRIORITY; + entry.vector = Core::Interrupt::PANIC; + writeEntry(slot, entry); + } + *IOREGSEL_REG = IOAPICID_IDX; + Identification IOAPICID{*IOWIN_REG}; + IOAPICID.id = APIC::getIOAPICID(); + *IOWIN_REG = IOAPICID.value; +} void config(uint8_t slot, Core::Interrupt::Vector vector, TriggerMode trigger_mode, Polarity polarity) { diff --git a/arch/ioapic.h b/arch/ioapic.h index 2f3480f..33e5e36 100644 --- a/arch/ioapic.h +++ b/arch/ioapic.h @@ -45,7 +45,7 @@ void init(); * \param polarity Polarity of the interrupt signaling (active high or active low) * - * \todo(12) Implement Function + * \todo Implement Function */ void config(uint8_t slot, Core::Interrupt::Vector vector, TriggerMode trigger_mode = TriggerMode::EDGE,