|
|
|
|
@ -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) {
|
|
|
|
|
|