IOAPIC: Difference between revisions

2,672 bytes added ,  12 years ago
no edit summary
[unchecked revision][unchecked revision]
No edit summary
No edit summary
Line 6:
 
== 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:contain IOAPICIDgeneral (indexinformations 0), which contains in bits 24 - 27 the APIC ID forabout 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 ''Maxremaing Redirectioncontain Entry''the (howspecific manyconfiguration IRQsfor caneach thisof handle - maxthe 24) in bits 16 - 23, finally IOAPICARB (index 2), which contains in bits 24 - 27 the APIC Arbitration IDIRQs.
 
== IOAPICID ==
This register has index 0 (you write 0 to IOREGSEL and then read from IOREGWIN). It's a Read Only registers with almost all bits reserved. The only interesting field is in bits 24 - 27: the APIC ID for this device (each peripheral which is interfaced with the APIC Bus needs an APIC ID, not only CPUs). You shall find this ID in ACPI/MP Tables as well.
 
== IOAPICVER ==
This register (index 1) contains the I/O APIC Version in bits 0 - 8, and the '''Max Redirection Entry''' which is "how many IRQs can this I/O APIC handle - 1". It cannot be higher than 23 (allowing 24 IRQs) and it's encoded in bits 16 - 23.
 
== IOAPICARB ==
This register (index 2) contains in bits 24 - 27 the APIC Arbitration ID. '''TODO'''
 
== IOREDTBL ==
Following there are two 32-bit register for each IRQ. The first IRQ has indexes 0x10 and 0x11, the second 0x12 and 0x13, the third 0x14 and 0x15, and so on. So the ''Redirection Entry'' register for IRQ ''n'' is 0x10 + n * 2 (+ 1). In the first of the two registers you access to the high dword, and the second for the low dword. Each redirection entry is made of the following fields:
{|
|-
! Field
! Bits
! Description
|-
| Vector
| 0 - 7
| The Interrupt vector that will be raised on the specified CPU(s).
|-
| Delivery Mode
| 8 - 10
| How the interrupt will be sent to the CPU(s). It can be 000 (Fixed), 001 (Lowest Priority), 010 (SMI), 100 (NMI), 101 (INIT) and 111 (ExtINT). Most of the cases you want Fixed mode, or Lowest Priority if you don't want to suspend a high priority task on some important Processor/Core/Thread.
|-
| Destination Mode
| 11
| Specify how the Destination field shall be interpreted. 0: Physical Destination, 1: Logical Destination
|-
| Delivery Status
| 12
| If 0, the IRQ is just relaxed and waiting for something to happen (or it has fired and already processed by Local APIC(s)). If 1, it means that the IRQ has been sent to the Local APICs but it's still waiting to be delivered.
| Pin Polarity
| 13
| 0: Active high, 1: Active low. For ISA IRQs assume Active High unless otherwise specified in Interrupt Source Override descriptors of the MADT or in the MP Tables.
| -
| Remote IRR
| 14
| '''TODO'''
| -
| Trigger Mode
| 15
| 0: Edge, 1: Level. For ISA IRQs assume Edge unless otherwise specified in Interrupt Source Override descriptors of the MADT or in the MP Tables.
| -
| Mask
| 16
| Just like in the old PIC, you can temporary disable this IRQ by setting this bit, and reenable it by clearing the bit.
| -
| Destination
| 56 - 63
| This field is interpreted according to the Destination Format bit. If Physical destination is choosen, then this field is limited to bits 56 - 59 (only 16 CPUs addressable). You put here the APIC ID of the CPU that you want to receive the interrupt. '''TODO''': Logical destination format...
|}
 
=== 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. 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.
 
<source lang="c">
Line 28 ⟶ 81:
}
</source>
Note: 'ptr_tuintptr_t' is the size of the default memory reference. If a 32-bit Protected Mode setup, it's equivalent to uint32_t, and uint64_t in 64-bit Long Mode environments. 'apic_base' is the memory base address for a selected IOAPIC, these can be found by enumerating them from the MP Tables.
 
== External Links ==
Anonymous user