Local Advanced Programmable Interrupt Controller — Änderungen 2720 → 2780

Zeile 57: Zeile 57:
 
| 0x0380 || r/w || 32 || || Initial Count Register
 
| 0x0380 || r/w || 32 || || Initial Count Register
 
|-
 
|-
−
| 0x0390 || r || 32 || || Current Count Register
+
| 0x0390 || r/w || 32 || || Current Count Register
 
|-
 
|-
 
| 0x03E0 || r/w || 32 || || Divide Configuration Register
 
| 0x03E0 || r/w || 32 || || Divide Configuration Register
Zeile 189: Zeile 189:
 
==== Codebeispiel: ====
 
==== Codebeispiel: ====
 
Dieser Code gehört in den anderen Init-Code für den APIC / Symmetric Mode. Er stellt den PIT auf den gewünschten Wert für den APIC Timer ein (hier 10ms), lässt die ISR des PITs den nötigen Wert für den Initial Count Value des APIC Timers berechnen und stellt diesen dann zugleich ein. Er setzt voraus, dass in der Variable [apicregs] die Adresse der APIC Register gespeichert ist.
 
Dieser Code gehört in den anderen Init-Code für den APIC / Symmetric Mode. Er stellt den PIT auf den gewünschten Wert für den APIC Timer ein (hier 10ms), lässt die ISR des PITs den nötigen Wert für den Initial Count Value des APIC Timers berechnen und stellt diesen dann zugleich ein. Er setzt voraus, dass in der Variable [apicregs] die Adresse der APIC Register gespeichert ist.
−
<asm> ;EBP nullen, damit nachher in PIT-ISR erkenbar, wie oft der Timer-Interrupt aufgerufen wurde
+
<asm> xor ebp,ebp ;EBP nullen, damit nachher in PIT-ISR erkenbar, wie oft der Timer-Interrupt aufgerufen wurde
−
xor ebp,ebp
 
  
−
;den PIT auf den gewünschten Wert (hier 10ms) einstellen
+
mov al,00110110b ;den PIT auf den gewünschten Wert (hier 10ms) einstellen
−
mov al,00110110b
 
 
out 43h,al
 
out 43h,al
 
 
Zeile 201: Zeile 199:
 
out 40h,al
 
out 40h,al
  
−
;IRQs freigeben
+
sti ;IRQs freigeben
−
sti
+
timerschleife: ;Solange Warten, bis das Einschalten und Messen des APIC Timers sicher fertig ist  
−
 
+
cmp ebp,0x3 ;Die Zählvariable hat dann den Wert 3
−
;Solange Warten, bis das Einschalten und Messen des APIC Timers sicher fertig ist
 
−
timerschleife:
 
−
 
 
−
;Die Zählvariable hat dann den Wert 3
 
−
cmp ebp,0x3
 
 
jne timerschleife
 
jne timerschleife
 
cli
 
cli
  
−
;Den zuvor ermittelten Platz der APIC Register laden
+
mov eax,[apicregs] ;Den zuvor ermittelten Platz der APIC Register laden
−
mov eax,[apicregs]
+
mov ecx,DWORD[apiczähler] ;Den Gemessenen Wert für den Initial Count des APIC Timers nach ECX laden
−
 
 
−
;Den Gemessenen Wert für den Initial Count des APIC Timers nach ECX laden
 
−
mov ecx,DWORD[apiczähler]
 
  
−
;Alle Register des APIC Timers neu schreiben, um den neuen Initial Count einzustellen
+
mov ebp,[eax+0x3e0] ;Alle Register des APIC Timers neu schreiben, um den neuen Initial Count einzustellen
−
mov ebp,[eax+0x3e0]
 
 
mov DWORD[eax+0x3e0],0xb
 
mov DWORD[eax+0x3e0],0xb
  
−
;Zuerst irgendein Register lesen, wegen Bug in manchem APICs
+
mov ebp,[eax+0x320] ;Zuerst irgendein Register lesen, wegen Bug in manchem APICS
−
mov ebp,[eax+0x320]
 
 
mov DWORD[eax+0x320],0x20031
 
mov DWORD[eax+0x320],0x20031
  
−
;Nach Lesen eines Wertes, den neuen Wert des Zählers aus ECX ins Initial Count Register schreiben
+
mov ebp,[eax+0x380] ;Nach Lesen eines Wertes, den neuen Wert des Zählers aus ECX ins Initial Count Register schreiben
−
mov ebp,[eax+0x380]
 
 
mov [eax+0x380],ecx</asm>
 
mov [eax+0x380],ecx</asm>
  
Zeile 233: Zeile 220:
 
Dieser Code muss als ISR des PITs eingetragen sein. Er kümmert sich zuerst um das Starten des APIC Timers und in einem zweiten Durchgang das Ablesen des heruntergezählten Wertes im Current Count Register. Er setzt voraus, dass in der Variable [apicregs] die Adresse der APIC Register gespeichert ist.
 
Dieser Code muss als ISR des PITs eingetragen sein. Er kümmert sich zuerst um das Starten des APIC Timers und in einem zweiten Durchgang das Ablesen des heruntergezählten Wertes im Current Count Register. Er setzt voraus, dass in der Variable [apicregs] die Adresse der APIC Register gespeichert ist.
 
<asm>APICkalibrieren:
 
<asm>APICkalibrieren:
−
 
+
inc ebp ;Variable um zwischen Einschalten und Messen (des Current Count) des APIC Timers zu unterscheiden  
−
;Variable um zwischen Einschalten und Messen (des Current Count) des APIC Timers zu unterscheiden  
+
mov eax,[apicregs] ;Den zuvor ermittelten Platz der APIC Register laden
−
inc ebp
 
−
 
 
−
;Den zuvor ermittelten Platz der APIC Register laden
 
−
mov eax,[apicregs]
 
  
 
cmp ebp,0x1
 
cmp ebp,0x1
Zeile 244: Zeile 227:
  
  
−
;Zuerst irgendein Wert auslesen, dannach Divide Configuration Register auf Divide Value = 1 setzen
+
mov edx,[eax+0x3e0] ;Zuerst irgendein Wert auslesen, dannach Divide Configuration Register auf Divide Value = 1 setzen
−
mov edx,[eax+0x3e0]
 
 
mov DWORD[eax+0x3e0],0xb
 
mov DWORD[eax+0x3e0],0xb
  
−
;Zuerst Wert auslesen, dannach LVT-Timer Register setzen (periodischer Timer auf Vektor 31)
+
mov edx,[eax+0x320] ;Zuerst Wert auslesen, dannach LVT-Timer Register setzen (peridischer Timer auf Vektor 31)
−
mov edx,[eax+0x320]
 
 
mov DWORD[eax+0x320],0x20031
 
mov DWORD[eax+0x320],0x20031
  
−
;Initial Count Register auf das Maximum setzen --> möglichst viel Werte zum Kalibrieren möglich
+
mov edx,[eax+0x380] ;Initial Count Register auf das Maximum setzen --> möglichst viel Werte zum Kalibrieren möglich
−
mov edx,[eax+0x380]
 
 
mov DWORD[eax+0x380],0xFFFFFFFF
 
mov DWORD[eax+0x380],0xFFFFFFFF
 
 
Zeile 260: Zeile 240:
  
 
ApicSchonGestartet:
 
ApicSchonGestartet:
−
 
+
cmp ebp,0x3 ;Wenn der Timer schon zum 3. Mal ausgelöst, muss nichts mehr getan werden
−
;Wenn der Timer schon zum 3. Mal ausgelöst, muss nichts mehr getan werden
 
−
cmp ebp,0x3
 
 
je schlussKalib
 
je schlussKalib
  
−
;Wenn Timer schon gestartet wurde, dann wird jetzt das Current Count Register gemessen
+
;Wenn Timer schon gestartet wurde, dann wird jetzt das Current Count Register gemessen
−
;Unterschied des Current Count in der Zeit des PITs ausrechnen
+
mov ecx,0xFFFFFFFF ;Unterschied des Current Count in der Zeit des PITs ausrechnen
−
mov ecx,0xFFFFFFFF
 
 
sub ecx,[eax+0x390]
 
sub ecx,[eax+0x390]
 
mov DWORD[apiczähler],ecx
 
mov DWORD[apiczähler],ecx
 
 
 
schlussKalib:
 
schlussKalib:
−
 
+
mov al,20h ;EOI senden an den PIC, da dieser verwendet wurde zum Kalibrieren
−
;EOI senden an den PIC, da dieser verwendet wurde zum Kalibrieren
 
−
mov al,20h
 
 
       out 20h,al
 
       out 20h,al
 
 
 
iret</asm>
 
iret</asm>
−
 
−
== Siehe auch ==
 
−
* [[APIC]]
 
  
 
== Weblinks ==
 
== Weblinks ==
 
* [http://www.intel.com/products/processor/manuals/index.htm Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 3A: System Programming Guide] (Kapitel 8)
 
* [http://www.intel.com/products/processor/manuals/index.htm Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 3A: System Programming Guide] (Kapitel 8)
 
* [http://www.amd.com/us-en/Processors/DevelopWithAMD/0,,30_2252_739_7044,00.html AMD64 Architecture Programmer's Manual Volume 2: System Programming] (Kapitel 16)
 
* [http://www.amd.com/us-en/Processors/DevelopWithAMD/0,,30_2252_739_7044,00.html AMD64 Architecture Programmer's Manual Volume 2: System Programming] (Kapitel 16)
 +
* [http://osdev.berlios.de/pic.html Advanced Programmable Interrupt Controller] (Tutorial von Mike Rieker)
  
 
[[Kategorie:Hardware]]
 
[[Kategorie:Hardware]]
 
[[Kategorie:Glossar]]
 
[[Kategorie:Glossar]]
 
[[Kategorie:Tutorials]]
 
[[Kategorie:Tutorials]]
−
[[Kategorie:Lizenz ungeklärt]]