I/O Advanced Programmable Interrupt Controller — Änderungen 6286 → 7123

Zeile 1: Zeile 1:
−
{{Stub}}
 
 
Die '''I/O APIC''' (= '''I/O Advanced Programmable Interrupt Controller''') löst den [[PIC | Programmable Interrupt Controller]] in einem [[SMP]]- bzw. [[NUMA]]-System ab. Da der PIC die [[IRQ | IRQs]] ausschließlich an den BSP (= Bootstrap Processor) senden kann, ist in einem System mit mehreren Prozessoren eine I/O APIC notwendig. Darüber hinaus stellt die I/O APIC statt nur 16 IRQ-Leitungen wie der PIC normalerweise 24 IRQ-Leitungen zur Verfügung. Dies verringert die Anzahl der von mehreren Geräten gleichzeitig genutzten IRQs in Systemen mit sehr vielen Geräten. Außerdem ist die Programmierung der I/O APIC schneller, da sie nicht über I/O Ports, sondern über Speicherbereiche abläuft.
 
Die '''I/O APIC''' (= '''I/O Advanced Programmable Interrupt Controller''') löst den [[PIC | Programmable Interrupt Controller]] in einem [[SMP]]- bzw. [[NUMA]]-System ab. Da der PIC die [[IRQ | IRQs]] ausschließlich an den BSP (= Bootstrap Processor) senden kann, ist in einem System mit mehreren Prozessoren eine I/O APIC notwendig. Darüber hinaus stellt die I/O APIC statt nur 16 IRQ-Leitungen wie der PIC normalerweise 24 IRQ-Leitungen zur Verfügung. Dies verringert die Anzahl der von mehreren Geräten gleichzeitig genutzten IRQs in Systemen mit sehr vielen Geräten. Außerdem ist die Programmierung der I/O APIC schneller, da sie nicht über I/O Ports, sondern über Speicherbereiche abläuft.
 +
 +
 +
== Aufbau ==
 +
 +
=== memory-mapped Register ===
 +
 +
Die folgenden Register sind in den physischen Adressraum des Systems eingeblendet und dienen dazu auf die [[I/O APIC#Interne Register | internen Register]] zuzugreifen:
 +
 +
 +
{| {{prettytable}}
 +
!Index
 +
!Abkürzung
 +
!Beschreibung
 +
!Zugriffsart
 +
|-
 +
| 0x00 || IOREGSEL || I/O Register Select || 8Bit, lesend/schreibend
 +
|-
 +
| 0x04 || IOWIN || I/O Window || 32Bit, lesend/schreibend
 +
|}
 +
 +
 +
=== Interne Register ===
 +
 +
Die folgenden Register dienen der Konfiguration der I/O APIC:
 +
 +
 +
{| {{prettytable}}
 +
!Index
 +
!Abkürzung
 +
!Beschreibung
 +
!Zugriffsart
 +
|-
 +
| 0x00 || IOAPICID || I/O APIC ID || 32Bit, lesend/schreibend
 +
|-
 +
| 0x01 || IOAPICVER || I/O APIC Version || 32Bit, nur lesend
 +
|-
 +
| 0x02 || IOAPICARB || I/O APIC Arbitration ID || 32Bit, nur lesend
 +
|-
 +
| 0x10 - ? || IOREDTBL[0-23] || ''Redirection Table''-Eintrag 0-? (jeweils 64bit) || 32Bit, lesend/schreibend
 +
|}
 +
 +
 +
==== I/O APIC ID ====
 +
 +
{| {{prettytable}}
 +
! Bits
 +
! Beschreibung
 +
! Zugriffsart
 +
|-
 +
| 28-31 || reserviert ||
 +
|-
 +
| 24-27 || 4Bit ID der I/O APIC || lesend/schreibend
 +
|-
 +
| 0-23 || reserviert ||
 +
|}
 +
 +
==== I/O APIC Version ====
 +
 +
{| {{prettytable}}
 +
! Bits
 +
! Beschreibung
 +
! Zugriffsart
 +
|-
 +
| 24-31 || reserviert ||
 +
|-
 +
| 26-23 || maximaler Index eines gültigen Eintrags in der ''Redirection Table'' || nur lesend
 +
|-
 +
| 8-15 || reserviert ||
 +
|-
 +
| 0-7 || I/O APIC Versionsnummer:<br> 0x11 = 82093AA || nur lesend
 +
|}
 +
 +
==== I/O APIC Arbitration ID ====
 +
 +
{| {{prettytable}}
 +
! Bits
 +
! Beschreibung
 +
! Zugriffsart
 +
|-
 +
| 28-31 || reserviert ||
 +
|-
 +
| 24-27 || 4Bit Arbitration ID der I/O APIC || lesend/schreibend
 +
|-
 +
| 0-23 || reserviert ||
 +
|}
 +
 +
==== Eintrag der ''Redirection Table'' ====
 +
 +
{| {{prettytable}}
 +
! Bits
 +
! Abkürzung
 +
! Name
 +
! Beschreibung
 +
! Zugriffsart
 +
|-
 +
| 56-63 || || Destination || gibt die empfangende(n) [[Local APIC]](s) an:
 +
 +
{| {{prettytable}}
 +
! Wert von DESTMOD
 +
! Modus
 +
! Beschreibung
 +
|-
 +
| 0 || Physical Mode || Bits 56-59 enthalten eine APIC ID
 +
|-
 +
| 1 || Logical Mode || Bits 56-63 werden als Menge von Prozessoren interpretiert
 +
|}
 +
 +
| lesend/schreibend
 +
|-
 +
| 17-55 || || || reserviert ||
 +
|-
 +
| 16 || || Interrupt Mask || Der Interrupt ist maskiert, falls der Wert 1 ist || lesend/schreibend
 +
|-
 +
| 15 || || Trigger Mode || 0b = edge sensitive<br>1b = level sensitive || lesend/schreibend
 +
|-
 +
| 14 || || Remote IRR || || nur lesend
 +
|-
 +
| 13 || INTPOL || Interrupt Input Pin Polarity || 0b = high active<br>1b = low active || lesend/schreibend
 +
|-
 +
| 12 || DELIVS || Delivery Status || Der Interrupt wird momentan ausgeliefert, falls der Wert 1 ist || nur lesend
 +
|-
 +
| 11 || DESTMOD || Destination Mode || Gibt an wie das Destination-Feld zur Adressierung der empfangenden [[Local APIC]]s interpretiert wird, siehe Destination-Feld || lesend/schreiben
 +
|-
 +
| 8-10
 +
| DELMOD
 +
| Delivery Mode
 +
| Gibt an wie die empfangenden [[Local APIC]]s reagieren sollen:
 +
 +
{| {{prettytable}}
 +
! Wert
 +
! Modus
 +
! Beschreibung
 +
|-
 +
| 000b || Fixed ||
 +
|-
 +
| 001b || niedrigste Priorität ||
 +
|-
 +
| 010b || [[SMI]] ||
 +
|-
 +
| 011b || reserviert
 +
|-
 +
| 100b || [[NMI]] ||
 +
|-
 +
| 101b || INIT ||
 +
|-
 +
| 110b || reserviert
 +
|-
 +
| 111b || ExtINT ||
 +
|}
 +
 +
| lesend/schreibend
 +
|-
 +
| 0-7 || INTVEC || Interrupt Vector || auszulösender Interruptvektor || lesend/schreibend
 +
|}
  
 
== Programmierung ==
 
== Programmierung ==
−
Die I/O APIC besitzt ein Indexregister (''I/O Register Select'' bzw. ''IOREGSEL'') und ein Datenregister (''I/O Window'' bzw. ''IOWIN''). Beide sind les- und schreibbar. Das Indexregister befindet sich an Offset 0x00 und das Datenregister an Offset 0x10 im Speicherbereich des I/O APIC, der bei einem PIIX3 Chipsatz bei 0xfec00xy00 (x und y werden mit dem APICBASE Register im PIIX3 festgelegt) beginnt. Im Allgemeinen ist die Basisadresse der I/O APICs über die [[Symmetrisches_Multiprozessorsystem#Intel_Multiprocessor_Specification | Multiprocessor Tabellen]] bzw. die [[ACPI | ACPI-Tabellen]] auslesbar. Mit dem Indexregister wählt man ein internes Register der I/O APIC aus und kann dann über das Datenregister das interne Register auslesen bzw. beschreiben.
+
 
 +
=== Basisadresse der I/O APIC ===
 +
 
 +
Die Basisadresse dieser Speicherbereiche kann im Allgemeinen über die [[Symmetrisches_Multiprozessorsystem#Intel_Multiprocessor_Specification | SMP]]- bzw. die [[ACPI | ACPI]]-Tabellen ausgelesen werden. Bei einem PIIX3 Chipsatz beginnt der Speicherbereich bei 0xFEC00xy00 (x und y werden mit dem APICBASE Register im PIIX3 festgelegt).
 +
 
 +
=== Lesen/Schreiben der internen Register ===
 +
Die I/O APIC besitzt ein Indexregister (''I/O Register Select'' bzw. ''IOREGSEL'') und ein Datenregister (''I/O Window'' bzw. ''IOWIN''). Mit dem Indexregister wählt man ein [[I/O APIC#Interne Register | internes Register]] der I/O APIC aus und kann anschließend über das Datenregister das interne Register auslesen bzw. beschreiben.
 +
 
 +
Folgender Code kann dazu verwendet werden auf die internen Register zuzugreifen:
 +
<c>
 +
/* Offset der memory-mapped Register */
 +
#define IO_APIC_MMREG_IOREGSEL 0x00
 +
#define IO_APIC_MMREG_IOWIN    0x04
 +
 
 +
/* Basisadresse, sollte vorher initialisiert werden */
 +
uint8_t * volatile io_apic_base;
 +
 
 +
/* Lesen eines internen Registers */
 +
uint32_t io_apic_read(uint8_t index)
 +
{
 +
  *(io_apic_base + IO_APIC_MMREG_IOREGSEL) = index;
 +
  return *(uint32_t * volatile)(io_apic_base + IO_APIC_MMREG_IOWIN);
 +
}
 +
 
 +
/* Schreiben eines internen Registers */
 +
void io_apic_write(uint8_t index, uint32_t value)
 +
{
 +
  *(io_apic_base + IO_APIC_MMREG_IOREGSEL) = index;
 +
  *(uint32_t * volatile)(io_apic_base + IO_APIC_MMREG_IOWIN) = value;
 +
}
 +
</c>
 +
 
 +
=== Setzen der Einträge der ''Redirection Table'' ===
 +
Die Einträge der ''Redirection Table'' werden basierend auf den Informationen, die die [[Symmetrisches_Multiprozessorsystem#Intel_Multiprocessor_Specification | SMP]]- bzw. die [[ACPI | ACPI]]-Tabellen enthalten, gesetzt.
  
 
== Weblinks ==
 
== Weblinks ==