| Zeile 61: | Zeile 61: | ||
<c>// Master-PIC initialisieren | <c>// Master-PIC initialisieren | ||
| − | + | outb(0x20, 0x11); // Initialisierungsbefehl fuer den PIC | |
| − | + | outb(0x21, 0x20); // Interruptnummer fuer IRQ 0 | |
| − | + | outb(0x21, 0x04); // An IRQ 2 haengt der Slave | |
| − | + | outb(0x21, 0x01); // ICW 4 | |
// Slave-PIC initialisieren | // Slave-PIC initialisieren | ||
| − | + | outb(0xa0, 0x11); // Initialisierungsbefehl fuer den PIC | |
| − | + | outb(0xa1, 0x28); // Interruptnummer fuer IRQ 8 | |
| − | + | outb(0xa1, 0x02); // An IRQ 2 haengt der Slave | |
| − | + | outb(0xa1, 0x01); // ICW 4 | |
// Alle IRQs aktivieren (demaskieren) | // Alle IRQs aktivieren (demaskieren) | ||
| Zeile 77: | Zeile 77: | ||
Dabei ist <i>outl</i> eine Funktion, um einen 32-Bit-Wert an einen [[IO-Port]] zu schreiben, und kann wie in [[Inline-Assembler mit GCC]] beschrieben definiert werden: | Dabei ist <i>outl</i> eine Funktion, um einen 32-Bit-Wert an einen [[IO-Port]] zu schreiben, und kann wie in [[Inline-Assembler mit GCC]] beschrieben definiert werden: | ||
| − | <c>static inline void | + | <c>static inline void outb(unsigned short port, unsigned char data) |
{ | { | ||
asm volatile ("outb %0, %1" : : "a" (data), "Nd" (port)); | asm volatile ("outb %0, %1" : : "a" (data), "Nd" (port)); | ||
| Zeile 122: | Zeile 122: | ||
.endm | .endm | ||
| − | + | // Exceptions | |
intr_stub 0 | intr_stub 0 | ||
intr_stub 1 | intr_stub 1 | ||
| Zeile 143: | Zeile 143: | ||
intr_stub 18 | intr_stub 18 | ||
| − | + | // IRQs | |
intr_stub 32 | intr_stub 32 | ||
| − | + | // usw. bis 47 | |
| − | + | // Syscall | |
intr_stub 48</asm> | intr_stub 48</asm> | ||
| Zeile 154: | Zeile 154: | ||
<asm>.extern handle_interrupt | <asm>.extern handle_interrupt | ||
intr_common_handler: | intr_common_handler: | ||
| + | // CPU-Zustand sichern | ||
push %ebp | push %ebp | ||
push %edi | push %edi | ||
| Zeile 162: | Zeile 163: | ||
push %eax | push %eax | ||
| + | // Handler aufrufen | ||
push %esp | push %esp | ||
call handle_interrupt | call handle_interrupt | ||
add $4, %esp | add $4, %esp | ||
| + | // CPU-Zustand wiederherstellen | ||
pop %eax | pop %eax | ||
pop %ebx | pop %ebx | ||
| Zeile 174: | Zeile 177: | ||
pop %ebp | pop %ebp | ||
| + | // Fehlercode und Interruptnummer vom Stack nehmen | ||
| + | add $8, %esp | ||
| + | |||
| + | // Ruecksprung zum unterbrochenen Code | ||
iret</asm> | iret</asm> | ||
| Zeile 201: | Zeile 208: | ||
<c>if (cpu->intr >= 0x20 && cpu->intr <= 0x2f) { | <c>if (cpu->intr >= 0x20 && cpu->intr <= 0x2f) { | ||
if (cpu->intr >= 0x28) { | if (cpu->intr >= 0x28) { | ||
| − | + | outb(0xa0, 0x20); | |
} | } | ||
| − | + | outb(0x20, 0x20); | |
}</c> | }</c> | ||