IOAPIC: Difference between revisions

m
no edit summary
[unchecked revision][unchecked revision]
(Fixed one link, marked others as dead; grammar/typo fixes.)
mNo edit summary
 
(9 intermediate revisions by 9 users not shown)
Line 1:
{{DISPLAYTITLE:I/O APIC}}
 
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]]. With the I/O APIC, interrupts can be distributed to physical or logical (clusters of) processors and can be prioritized. Each I/O APIC typically handles 24 external interrupts.
 
Line 5 ⟶ 7:
 
== Programming the I/O APIC ==
Each I/O APIC has a set of 2 or 3 (depending on version) 32-bit registers and up to many 64-bit registers (one per IRQ). The 64-bit registers have actually to be accessed as two 32-bit reads/writes. 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 contain general information about this I/O APIC, while the remaining registers contain the specific configuration for each IRQ.
 
=== IOAPICID ===
Line 11 ⟶ 13:
 
=== IOAPICVER ===
This register (index 1) contains the I/O APIC Version in bits 0 - 87, and the '''Max Redirection Entry''' which is "how many IRQs can this I/O APIC handle - 1". It is encoded in bits 16 - 23.
 
=== IOAPICARB ===
Line 64 ⟶ 66:
The register IOREGSEL is an MMIO register select register that is used to access all the other I/O APIC registers. 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. The actual position in memory of the two registers is specified in the ACPI MADT Table and/or in the MP table. The IOREGSEL is at the address specified, and IOREGWIN is at the same address + 0x10.
 
<sourcesyntaxhighlight lang="cpp">
 
#define IOAPICID 0x00
Line 144 ⟶ 146:
this->virtAddr = KernelMemory::allocatePage(PAGE_SIZE);
 
/* map virtAddr to physical-regs. Note that you'reyour paging code may not support
automatically aligning physRegs to page-boundaries. Be sure to check! */
EnsureMapping(virtAddr, physRegs, PagePresent | PageReadWrite | PageCacheDisable);
Line 247 ⟶ 249:
}
};
</syntaxhighlight>
</source>
'apic_base' is the memory base address for a selected IOAPIC, these can be found by enumerating them from the MP or ACPI Tables.
 
Line 253 ⟶ 255:
== IO APIC Inputs ==
 
How other hardware (devices, etc) use IO APIC inputs is completely arbitrary - the motherboard/chipset designer can hard-wire anything they like to any IO APIC input. For the motherboard designer's convenience, most but not all legacy IRQs are often (but not always) connected "1:1" to IO APIC inputs (e.g. IO APIC input #1 may be the same as PIC chip input #1) as this makes firmware a little easier (e.g. no need for "interrupt redirection entries" in ACPI's MASDMADT/APIC table), but this is not a requirement of any standard and not something that useful operating system software can rely on.
 
To correctly determine what how IO APIC inputs are used (and how they must be configured - as active high or active low, and as edge triggered or level triggered) operating system software must either:
Line 264 ⟶ 266:
 
4) Use an excessively "clever" auto-detection scheme (with a high risk of misconfiguration and race conditions). These schemes typically begin with whatever information can be obtained easily (e.g. determining legacy IRQs from ACPI's MADT/APIC table), assuming everything else can be configured as "level triggered active low" (to suit PCI), and then asking device drivers to repeatedly forcing their device to generate an IRQ (while ruling out IO APIC inputs that weren't triggered within a certain period of time after the IRQ was caused) until the specific IO APIC that the device uses can be determined.
 
 
== External Links ==
Line 271 ⟶ 272:
 
=== I/O APIC ===
* [http://web.archive.org/web/20161130153145/http://download.intel.com/design/chipsets/datashts/29056601.pdf Intel 82093AA I/O APIC] (dead link)
* [http://web.archive.org/web/20140713224739/http://download.intel.com/design/processor/manuals/253668.pdf Intel SDM 3A (see ch.chapter 9.9)] (dead link)
 
[[de:I/O Advanced Programmable Interrupt Controller]]