selectors, descriptors, more interrupt init
[3sys] / sys1 / kern / src / intr.asm
1         bits 32
2         section .text
3
4         extern intr_handler
5
6 PIC1_CMD_PORT   equ 0x20
7 PIC1_DATA_PORT  equ 0x21
8 PIC2_CMD_PORT   equ 0xa0
9 PIC2_DATA_PORT  equ 0xa1
10
11 ICW1_ICW4_NEEDED equ 0x01
12 ICW1_INIT       equ 0x10
13 ICW4_8086       equ 0x01
14
15 OCW2_EOI        equ 0x20
16 OCW3_ISR        equ 0x0b
17
18         global set_idt
19 set_idt:
20         mov eax, [esp + 4]
21         mov [idtbase], eax
22         mov ax, [esp + 8]
23         mov [idtlim], ax
24         lidt [idtlim]
25         ret
26
27         align 4
28         dw 0
29 idtlim  dw 0
30 idtbase dd 0
31
32
33         global prog_pic
34 prog_pic:
35         ; send ICW1 saying we'll follow with ICW4 later
36         mov al, ICW1_INIT | ICW1_ICW4_NEEDED
37         out PIC1_CMD_PORT, al
38         ; send ICW2 with IRQ remapping
39         mov al, [esp + 4]
40         out PIC1_DATA_PORT, al
41         add al, 8
42         out PIC2_DATA_PORT, al
43         ; send ICW3 to setup the master/slave relationship
44         ; ... set bit3 = 3rd interrupt input has a slave
45         mov al, 4
46         out PIC1_DATA_PORT, al
47         ; ... set slave id to 2
48         mov al, 2
49         OUT PIC2_DATA_PORT, al
50         ; send ICW4 to set 8086 mode (no calls generated)
51         mov al, ICW4_8086
52         out PIC1_DATA_PORT, al
53         out PIC2_DATA_PORT, al
54         ; done, reset the data port to 0
55         xor al, al
56         out PIC1_DATA_PORT, al
57         out PIC2_DATA_PORT, al
58         ret
59
60
61         global end_of_irq
62 end_of_irq:
63         mov eax, [esp + 4]
64         cmp eax, 8
65         jb .eoi_master
66         ; cascaded IRQ, send EOI to slave PIC first
67         mov al, OCW2_EOI
68         out PIC2_CMD_PORT, al
69 .eoi_master: ; send EOI to master PIC
70         mov al, OCW2_EOI
71         out PIC1_CMD_PORT, al
72         ret
73
74
75         ; special entry point for IRQ7 to catch and disregard spurious interrupts
76         global intr_entry_irq7_verify
77 intr_entry_irq7_verify:
78         push eax
79         mov al, OCW3_ISR
80         out PIC1_CMD_PORT, al
81         in al, PIC1_CMD_PORT
82         and al, 0x80
83         pop eax
84         jnz intr_entry_irq7
85         iret
86
87         global intr_entry_irq15_verify
88 intr_entry_irq15_verify:
89         ; similarly for IRQ15
90         push eax
91         mov al, OCW3_ISR
92         out PIC2_CMD_PORT, al
93         in al, PIC2_CMD_PORT
94         and al, 0x80
95         jnz .valid
96         ; it was spurious, send EOI to master PIC and iret
97         mov al, OCW2_EOI
98         out PIC1_CMD_PORT, al
99         pop eax
100         iret
101 .valid: pop eax
102         jmp intr_entry_irq15
103
104
105 %macro intr_entry_err 2
106         global intr_entry_%2
107 intr_entry_%2:
108         push dword %1   ; push interrupt number
109         jmp intr_entry_common
110 %endmacro
111
112 %macro intr_entry_noerr 2
113         global intr_entry_%2
114 intr_entry_%2:
115         push dword 0    ; push dummy error code
116         push dword %1   ; push interrupt number
117         jmp intr_entry_common
118 %endmacro
119
120 intr_entry_common:
121         pusha           ; save general purpose registers
122         call intr_handler
123         popa            ; restore general purpose registers
124         add esp, 8      ; remove error code and intr number from the stack
125         iret
126
127         ; interrupt entry points
128         intr_entry_noerr 0, div
129         intr_entry_noerr 1, debug
130         intr_entry_noerr 2, nmi
131         intr_entry_noerr 3, bpt
132         intr_entry_noerr 4, ovf
133         intr_entry_noerr 5, bound
134         intr_entry_noerr 6, ill
135         intr_entry_noerr 7, nodev
136         intr_entry_err 8, dbl
137         intr_entry_noerr 9, copseg
138         intr_entry_err 10, tss
139         intr_entry_err 11, segpres
140         intr_entry_err 12, stack
141         intr_entry_err 13, prot
142         intr_entry_err 14, page
143         intr_entry_noerr 16, fpu
144         intr_entry_err 17, align
145         intr_entry_noerr 18, mce
146         intr_entry_noerr 19, sse
147         ; remapped IRQs 0-15 -> 32-47
148         intr_entry_noerr 32, irq0
149         intr_entry_noerr 33, irq1
150         intr_entry_noerr 34, irq2
151         intr_entry_noerr 35, irq3
152         intr_entry_noerr 36, irq4
153         intr_entry_noerr 37, irq5
154         intr_entry_noerr 38, irq6
155         intr_entry_noerr 39, irq7
156         intr_entry_noerr 40, irq8
157         intr_entry_noerr 41, irq9
158         intr_entry_noerr 42, irq10
159         intr_entry_noerr 43, irq11
160         intr_entry_noerr 44, irq12
161         intr_entry_noerr 45, irq13
162         intr_entry_noerr 46, irq14
163         intr_entry_noerr 47, irq15
164         ; default handler
165         intr_entry_noerr 255, default
166
167 ; vi:ft=nasm: