OOStuBS/MPStuBS
Informationen zum APIC-Timer

Die APIC-Architektur beinhaltet auf jedem der CPU-lokalen APICs einen hochauflösenden Timer, der zum Generieren von Interrupts genutzt werden kann.

Da seine Frequenz nicht in der Spezifikation festgelegt ist, muss sie zunächst durch Kalibration mit einer anderen Zeitquelle deren Frequenz bekannt ist, beispielsweise dem Programmable Interrupt Timer (PIT), bestimmt werden. In der Vorgabe zu OOStuBS ist dieser Code bereits enthalten, er nutzt dazu jedoch eine generische Methode zur Timerkonfiguration, die noch zu implementieren ist.

Programmierung des Timers

Vier 32bit-Register (memory-mapped) sind für die Programmierung des APIC-Timers verantwortlich:

AddresseRegistername
0xfee00320LVT Timer Register (aka Timer Control Register)
0xfee00380Initial Count Register (ICR)
0xfee00390Current Count Register (CCR)
0xfee003e0Divide Configuration Register

Die beiden Count-Register (ICR und CCR) dienen dazu, den Startwert des Timers zu setzen beziehungsweise den aktuellen Wert auszulesen. Zusätzlich kann mit einem ICR-Wert von 0 der Timer vor einer Umprogrammierung komplett gestoppt werden. Ein anschließendes Schreiben des ICR mit einem Wert ungleich 0 startet den Timer.

Das Verhalten des Timers kann über das Kontrollregister und den Divisor beeinflusst werden. Der Aufbau des Kontrollregisters ist:

Bit(s)WertBedeutung
31-18(reserviert)
17Betriebsmodus
0 one-shot (stoppt bei 0)
1 periodic (startet wieder mit ICR-Wert)
16Interruptmaske
0 Interrupts werden zugestellt
1 Interrupts sind deaktiviert
15-13(reserviert)
12Interrupt-Status (read-only)
0 idle
1 Interrupt pending
11-8(reserviert)
7-0Vektornummer
des auszulösenden Interrupts

Die Zuordnung des Divisors auf entsprechende Registerwerte ist dem Intel-Manual zu entnehmen, aber auch bereits durch die Hilfsfunktion LAPIC::timer_div() als Teil der Vorgabe implementiert.