Anonymous user
IOAPIC: Difference between revisions
no edit summary
[unchecked revision] | [unchecked revision] |
m (Interwiki) |
No edit summary |
||
Line 1:
== Basic Info ==
The Intel I/O Advanced Programmable Interrupt Controller is used to distribute external interrupts in a more advanced manner than that of the standard [[8259 PIC]].
== Detecting I/O APIC ==
In order to detect the existence of an I/O APIC (or multiple ones), the Intel Multi-Processor or ACPI tables must be parsed.
== Programming the I/O APIC ==
Each I/O APIC has a set of 3 32-bit registers and up to 24 64-bit registers (one per IRQ). The 64-bit registers have actually to be accessed as two 32-bit reads/writes. So here we have 51 registers. All registers are memory indexed. It means that you actually have only two 32-bit registers in memory, called IOREGSEL and IOREGWIN. You put the register index in IOREGSEL, and then you can read/write in IOREGWIN. The first three registers are: IOAPICID (index 0), which contains in bits 24 - 27 the APIC ID for this "device" (should be the same in MP/ACPI MADT Tables), IOAPICVER (index 1), which contains the I/O APIC Version in bits 0 - 8, and the ''Max Redirection Entry'' (how many IRQs can this handle - max 24) in bits 16 - 23, finally IOAPICARB (index 2), which contains in bits 24 - 27 the APIC Arbitration ID.
=== IOREGSEL and IOWIN ===
The register IOREGSEL is an MMIO register select register that is used to access all the other I/O APIC registers. IOREGSEL only selects the register and does not actually write or read the register. The IOWIN register is the 'data' register. Once the IOREGSEL register has been set, the IOWIN register can be used to write or read the register in the IOREGSEL.
<source lang="c">
void write_ioapic_register(const
{
/* tell IOREGSEL where we want to write to */
Line 18 ⟶ 20:
}
uint32_t read_ioapic_register(const
{
/* tell IOREGSEL where we want to read from */
|