Rev 2212 | Rev 2219 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2212 | Rev 2217 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
5 | ;; ;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
7 | 7 | ||
8 | IRQ_RESERVED = 24 ; 16 or 24 |
8 | IRQ_RESERVED = 24 ; 16 or 24 |
9 | 9 | ||
10 | iglobal |
10 | iglobal |
11 | IRQ_COUNT dd 24 |
11 | IRQ_COUNT dd 24 |
12 | endg |
12 | endg |
13 | 13 | ||
14 | uglobal |
14 | uglobal |
15 | APIC rd 1 |
15 | APIC rd 1 |
16 | IOAPIC_base rd 1 |
16 | IOAPIC_base rd 1 |
17 | LAPIC_BASE rd 1 |
17 | LAPIC_BASE rd 1 |
18 | endg |
18 | endg |
19 | 19 | ||
20 | APIC_ID equ 0x20 |
20 | APIC_ID equ 0x20 |
21 | APIC_TPR equ 0x80 |
21 | APIC_TPR equ 0x80 |
22 | APIC_EOI equ 0xb0 |
22 | APIC_EOI equ 0xb0 |
23 | APIC_LDR equ 0xd0 |
23 | APIC_LDR equ 0xd0 |
24 | APIC_DFR equ 0xe0 |
24 | APIC_DFR equ 0xe0 |
25 | APIC_SVR equ 0xf0 |
25 | APIC_SVR equ 0xf0 |
26 | APIC_ISR equ 0x100 |
26 | APIC_ISR equ 0x100 |
27 | APIC_ESR equ 0x280 |
27 | APIC_ESR equ 0x280 |
28 | APIC_ICRL equ 0x300 |
28 | APIC_ICRL equ 0x300 |
29 | APIC_ICRH equ 0x310 |
29 | APIC_ICRH equ 0x310 |
30 | APIC_LVT_LINT0 equ 0x350 |
30 | APIC_LVT_LINT0 equ 0x350 |
31 | APIC_LVT_LINT1 equ 0x360 |
31 | APIC_LVT_LINT1 equ 0x360 |
32 | APIC_LVT_err equ 0x370 |
32 | APIC_LVT_err equ 0x370 |
33 | 33 | ||
34 | ; APIC timer |
34 | ; APIC timer |
35 | APIC_LVT_timer equ 0x320 |
35 | APIC_LVT_timer equ 0x320 |
36 | APIC_timer_div equ 0x3e0 |
36 | APIC_timer_div equ 0x3e0 |
37 | APIC_timer_init equ 0x380 |
37 | APIC_timer_init equ 0x380 |
38 | APIC_timer_cur equ 0x390 |
38 | APIC_timer_cur equ 0x390 |
39 | ; IOAPIC |
39 | ; IOAPIC |
40 | IOAPIC_ID equ 0x0 |
40 | IOAPIC_ID equ 0x0 |
41 | IOAPIC_VER equ 0x1 |
41 | IOAPIC_VER equ 0x1 |
42 | IOAPIC_ARB equ 0x2 |
42 | IOAPIC_ARB equ 0x2 |
43 | IOAPIC_REDTBL equ 0x10 |
43 | IOAPIC_REDTBL equ 0x10 |
- | 44 | ||
44 | 45 | align 4 |
|
45 | APIC_init: |
46 | APIC_init: |
46 | mov dword[APIC], 0 |
47 | mov dword[APIC], 0 |
47 | 48 | ||
48 | mov eax, [acpi_ioapic_base] |
49 | mov eax, [acpi_ioapic_base] |
49 | test eax, eax |
50 | test eax, eax |
50 | jz .no_apic |
51 | jz .no_apic |
51 | 52 | ||
52 | call IRQ_mask_all |
53 | call IRQ_mask_all |
53 | 54 | ||
54 | ; IOAPIC init |
55 | ; IOAPIC init |
55 | stdcall map_io_mem, [acpi_ioapic_base], 0x20, PG_SW |
56 | stdcall map_io_mem, [acpi_ioapic_base], 0x20, PG_SW |
56 | mov [IOAPIC_base], eax |
57 | mov [IOAPIC_base], eax |
57 | 58 | ||
58 | mov eax, IOAPIC_VER |
59 | mov eax, IOAPIC_VER |
59 | call IOAPIC_read |
60 | call IOAPIC_read |
60 | shr eax, 16 |
61 | shr eax, 16 |
61 | inc al |
62 | inc al |
62 | movzx eax, al |
63 | movzx eax, al |
63 | cmp al, IRQ_RESERVED |
64 | cmp al, IRQ_RESERVED |
64 | jbe @f |
65 | jbe @f |
- | 66 | ||
65 | mov al, IRQ_RESERVED |
67 | mov al, IRQ_RESERVED |
66 | @@: |
68 | @@: |
67 | mov [IRQ_COUNT], eax |
69 | mov [IRQ_COUNT], eax |
68 | 70 | ||
69 | ; Reroute IOAPIC & mask all interrupts |
71 | ; Reroute IOAPIC & mask all interrupts |
70 | xor ecx, ecx |
72 | xor ecx, ecx |
71 | mov eax, IOAPIC_REDTBL |
73 | mov eax, IOAPIC_REDTBL |
- | 74 | @@: |
|
72 | @@: mov ebx, eax |
75 | mov ebx, eax |
73 | call IOAPIC_read |
76 | call IOAPIC_read |
74 | mov ah, 0x09 ; Delivery Mode: Lowest Priority, Destination Mode: Logical |
77 | mov ah, 0x09 ; Delivery Mode: Lowest Priority, Destination Mode: Logical |
75 | mov al, cl |
78 | mov al, cl |
76 | add al, 0x20 ; vector |
79 | add al, 0x20 ; vector |
77 | or eax, 0x10000 ; Mask Interrupt |
80 | or eax, 0x10000 ; Mask Interrupt |
78 | cmp ecx, 16 |
81 | cmp ecx, 16 |
79 | jb .set |
82 | jb .set |
- | 83 | ||
80 | or eax, 0xa000 ;<<< level-triggered active-low for IRQ16+ |
84 | or eax, 0xa000 ;<<< level-triggered active-low for IRQ16+ |
81 | .set: |
85 | .set: |
82 | xchg eax, ebx |
86 | xchg eax, ebx |
83 | call IOAPIC_write |
87 | call IOAPIC_write |
84 | inc eax |
88 | inc eax |
85 | mov ebx, eax |
89 | mov ebx, eax |
86 | call IOAPIC_read |
90 | call IOAPIC_read |
87 | or eax, 0xff000000 ; Destination Field |
91 | or eax, 0xff000000 ; Destination Field |
88 | xchg eax, ebx |
92 | xchg eax, ebx |
89 | call IOAPIC_write |
93 | call IOAPIC_write |
90 | inc eax |
94 | inc eax |
91 | inc ecx |
95 | inc ecx |
92 | cmp ecx, [IRQ_COUNT] |
96 | cmp ecx, [IRQ_COUNT] |
93 | jb @b |
97 | jb @b |
94 | 98 | ||
95 | call LAPIC_init |
99 | call LAPIC_init |
96 | 100 | ||
97 | mov dword[APIC], 0xffffffff |
101 | mov dword[APIC], 0xffffffff |
98 | 102 | ||
99 | mov al, 0x70 |
103 | mov al, 0x70 |
100 | out 0x22, al |
104 | out 0x22, al |
101 | mov al, 1 |
105 | mov al, 1 |
102 | out 0x23, al |
106 | out 0x23, al |
103 | 107 | ||
104 | ; mov dword[irq_type_to_set], IRQ_TYPE_APIC |
108 | ; mov dword[irq_type_to_set], IRQ_TYPE_APIC |
- | 109 | ||
- | 110 | .no_apic: |
|
105 | 111 | ||
106 | ;init handlers table |
112 | ;init handlers table |
107 | 113 | ||
108 | mov ecx, IRQ_RESERVED |
114 | mov ecx, IRQ_RESERVED |
109 | mov edi, irqh_tab |
115 | mov edi, irqh_tab |
110 | @@: |
116 | @@: |
111 | mov eax, edi |
117 | mov eax, edi |
112 | stosd |
118 | stosd |
113 | stosd |
119 | stosd |
114 | loop @B |
120 | loop @B |
115 | 121 | ||
116 | mov ecx, 47 |
122 | mov ecx, 47 |
117 | mov eax, irqh_pool+IRQH.sizeof |
123 | mov eax, irqh_pool+IRQH.sizeof |
118 | mov [next_irqh], irqh_pool |
124 | mov [next_irqh], irqh_pool |
119 | - | ||
120 | @@: |
125 | @@: |
121 | mov [eax-IRQH.sizeof], eax |
126 | mov [eax-IRQH.sizeof], eax |
122 | add eax, IRQH.sizeof |
127 | add eax, IRQH.sizeof |
123 | loop @B |
128 | loop @B |
124 | 129 | ||
125 | mov [eax-IRQH.sizeof], dword 0 |
130 | mov [eax-IRQH.sizeof], dword 0 |
126 | - | ||
127 | .no_apic: |
131 | |
128 | ret |
132 | ret |
129 | 133 | ||
130 | ;=========================================================== |
134 | ;=========================================================== |
131 | align 4 |
135 | align 4 |
132 | LAPIC_init: |
136 | LAPIC_init: |
133 | ; Check MSR support |
137 | ; Check MSR support |
134 | ;.... |
138 | ;.... |
135 | ; Get LAPIC base address |
139 | ; Get LAPIC base address |
136 | ; mov ecx, 0x1b |
140 | ; mov ecx, 0x1b |
137 | ; rdmsr ; it may be replaced to |
141 | ; rdmsr ; it may be replaced to |
138 | ; and ax, 0xf000 ; mov eax, 0xfee00000 |
142 | ; and ax, 0xf000 ; mov eax, 0xfee00000 |
139 | 143 | ||
140 | stdcall map_io_mem, [acpi_lapic_base], 0x1000, PG_SW |
144 | stdcall map_io_mem, [acpi_lapic_base], 0x1000, PG_SW |
141 | mov [LAPIC_BASE], eax |
145 | mov [LAPIC_BASE], eax |
142 | mov esi, eax |
146 | mov esi, eax |
143 | 147 | ||
144 | ; Program Destination Format Register for Flat mode. |
148 | ; Program Destination Format Register for Flat mode. |
145 | mov eax, [esi + APIC_DFR] |
149 | mov eax, [esi + APIC_DFR] |
146 | or eax, 0xf0000000 |
150 | or eax, 0xf0000000 |
147 | mov [esi + APIC_DFR], eax |
151 | mov [esi + APIC_DFR], eax |
148 | - | ||
149 | 152 | ||
150 | ; Program Logical Destination Register. |
153 | ; Program Logical Destination Register. |
151 | mov eax, [esi + APIC_LDR] |
154 | mov eax, [esi + APIC_LDR] |
152 | ;and eax, 0xff000000 |
155 | ;and eax, 0xff000000 |
153 | and eax, 0x00ffffff |
156 | and eax, 0x00ffffff |
154 | or eax, 0x01000000 ;!!!!!!!!!!!! |
157 | or eax, 0x01000000 ;!!!!!!!!!!!! |
155 | mov [esi + APIC_LDR], eax |
158 | mov [esi + APIC_LDR], eax |
156 | 159 | ||
157 | ; Task Priority Register initialization. |
160 | ; Task Priority Register initialization. |
158 | mov eax, [esi + APIC_TPR] |
161 | mov eax, [esi + APIC_TPR] |
159 | and eax, 0xffffff00 |
162 | and eax, 0xffffff00 |
160 | mov [esi + APIC_TPR], eax |
163 | mov [esi + APIC_TPR], eax |
161 | 164 | ||
162 | ; Flush the queue |
165 | ; Flush the queue |
163 | mov edx, 0 |
166 | mov edx, 0 |
- | 167 | .nxt2: |
|
164 | .nxt2: mov ecx, 32 |
168 | mov ecx, 32 |
165 | mov eax, [esi + APIC_ISR + edx] |
169 | mov eax, [esi + APIC_ISR + edx] |
- | 170 | .nxt: |
|
166 | .nxt: shr eax, 1 |
171 | shr eax, 1 |
167 | jnc @f |
172 | jnc @f |
168 | mov dword [esi + APIC_EOI], 0 ; EOI |
173 | mov dword [esi + APIC_EOI], 0 ; EOI |
- | 174 | @@: |
|
169 | @@: loop .nxt |
175 | loop .nxt |
- | 176 | ||
170 | add edx, 0x10 |
177 | add edx, 0x10 |
171 | cmp edx, 0x170 |
178 | cmp edx, 0x170 |
172 | jbe .nxt2 |
179 | jbe .nxt2 |
173 | 180 | ||
174 | ; Spurious-Interrupt Vector Register initialization. |
181 | ; Spurious-Interrupt Vector Register initialization. |
175 | mov eax, [esi + APIC_SVR] |
182 | mov eax, [esi + APIC_SVR] |
176 | or eax, 0x1ff |
183 | or eax, 0x1ff |
177 | and eax, 0xfffffdff |
184 | and eax, 0xfffffdff |
178 | mov [esi + APIC_SVR], eax |
185 | mov [esi + APIC_SVR], eax |
179 | 186 | ||
180 | ; Initialize LVT LINT0 register. (INTR) |
187 | ; Initialize LVT LINT0 register. (INTR) |
181 | mov eax, 0x00700 |
188 | mov eax, 0x00700 |
182 | ; mov eax, 0x10700 |
189 | ; mov eax, 0x10700 |
183 | mov [esi + APIC_LVT_LINT0], eax |
190 | mov [esi + APIC_LVT_LINT0], eax |
184 | 191 | ||
185 | ; Initialize LVT LINT1 register. (NMI) |
192 | ; Initialize LVT LINT1 register. (NMI) |
186 | mov eax, 0x00400 |
193 | mov eax, 0x00400 |
187 | mov [esi + APIC_LVT_LINT1], eax |
194 | mov [esi + APIC_LVT_LINT1], eax |
188 | 195 | ||
189 | ; Initialize LVT Error register. |
196 | ; Initialize LVT Error register. |
190 | mov eax, [esi + APIC_LVT_err] |
197 | mov eax, [esi + APIC_LVT_err] |
191 | or eax, 0x10000 ; bit 16 |
198 | or eax, 0x10000 ; bit 16 |
192 | mov [esi + APIC_LVT_err], eax |
199 | mov [esi + APIC_LVT_err], eax |
193 | 200 | ||
194 | ; LAPIC timer |
201 | ; LAPIC timer |
195 | ; pre init |
202 | ; pre init |
196 | mov dword[esi + APIC_timer_div], 1011b ; 1 |
203 | mov dword[esi + APIC_timer_div], 1011b ; 1 |
197 | mov dword[esi + APIC_timer_init], 0xffffffff ; max val |
204 | mov dword[esi + APIC_timer_init], 0xffffffff ; max val |
198 | push esi |
205 | push esi |
199 | mov esi, 640 ; wait 0.64 sec |
206 | mov esi, 640 ; wait 0.64 sec |
200 | call delay_ms |
207 | call delay_ms |
201 | pop esi |
208 | pop esi |
202 | mov eax, [esi + APIC_timer_cur] ; read current tick couner |
209 | mov eax, [esi + APIC_timer_cur] ; read current tick couner |
203 | xor eax, 0xffffffff ; eax = 0xffffffff - eax |
210 | xor eax, 0xffffffff ; eax = 0xffffffff - eax |
204 | shr eax, 6 ; eax /= 64; APIC ticks per 0.01 sec |
211 | shr eax, 6 ; eax /= 64; APIC ticks per 0.01 sec |
205 | 212 | ||
206 | ; Start (every 0.01 sec) |
213 | ; Start (every 0.01 sec) |
207 | mov dword[esi + APIC_LVT_timer], 0x30020 ; periodic int 0x20 |
214 | mov dword[esi + APIC_LVT_timer], 0x30020 ; periodic int 0x20 |
208 | mov dword[esi + APIC_timer_init], eax |
215 | mov dword[esi + APIC_timer_init], eax |
209 | - | ||
210 | ret |
216 | ret |
- | 217 | ||
211 | ;=========================================================== |
218 | ;=========================================================== |
212 | ; IOAPIC implementation |
219 | ; IOAPIC implementation |
213 | align 4 |
220 | align 4 |
214 | IOAPIC_read: |
221 | IOAPIC_read: |
215 | ; in : EAX - IOAPIC register |
222 | ; in : EAX - IOAPIC register |
216 | ; out: EAX - readed value |
223 | ; out: EAX - readed value |
217 | push esi |
224 | push esi |
218 | mov esi, [IOAPIC_base] |
225 | mov esi, [IOAPIC_base] |
219 | mov [esi], eax |
226 | mov [esi], eax |
220 | mov eax, [esi + 0x10] |
227 | mov eax, [esi + 0x10] |
221 | pop esi |
228 | pop esi |
222 | ret |
229 | ret |
- | 230 | ||
223 | align 4 |
231 | align 4 |
224 | IOAPIC_write: |
232 | IOAPIC_write: |
225 | ; in : EAX - IOAPIC register |
233 | ; in : EAX - IOAPIC register |
226 | ; EBX - value |
234 | ; EBX - value |
227 | ; out: none |
235 | ; out: none |
228 | push esi |
236 | push esi |
229 | mov esi, [IOAPIC_base] |
237 | mov esi, [IOAPIC_base] |
230 | mov [esi], eax |
238 | mov [esi], eax |
231 | mov [esi + 0x10], ebx |
239 | mov [esi + 0x10], ebx |
232 | pop esi |
240 | pop esi |
233 | ret |
241 | ret |
234 | ;=========================================================== |
242 | ;=========================================================== |
235 | ; Remap all IRQ to 0x20+ Vectors |
243 | ; Remap all IRQ to 0x20+ Vectors |
236 | ; IRQ0 to vector 0x20, IRQ1 to vector 0x21.... |
244 | ; IRQ0 to vector 0x20, IRQ1 to vector 0x21.... |
237 | PIC_init: |
245 | PIC_init: |
238 | cli |
246 | cli |
239 | mov al,0x11 ; icw4, edge triggered |
247 | mov al,0x11 ; icw4, edge triggered |
240 | out 0x20,al |
248 | out 0x20,al |
241 | call pic_delay |
- | |
242 | out 0xA0,al |
249 | out 0xA0,al |
243 | call pic_delay |
- | |
244 | 250 | ||
245 | mov al,0x20 ; generate 0x20 + |
251 | mov al,0x20 ; generate 0x20 + |
246 | out 0x21,al |
252 | out 0x21,al |
247 | call pic_delay |
- | |
248 | mov al,0x28 ; generate 0x28 + |
253 | mov al,0x28 ; generate 0x28 + |
249 | out 0xA1,al |
254 | out 0xA1,al |
250 | call pic_delay |
- | |
251 | 255 | ||
252 | mov al,0x04 ; slave at irq2 |
256 | mov al,0x04 ; slave at irq2 |
253 | out 0x21,al |
257 | out 0x21,al |
254 | call pic_delay |
- | |
255 | mov al,0x02 ; at irq9 |
258 | mov al,0x02 ; at irq9 |
256 | out 0xA1,al |
259 | out 0xA1,al |
257 | call pic_delay |
- | |
258 | 260 | ||
259 | mov al,0x01 ; 8086 mode |
261 | mov al,0x01 ; 8086 mode |
260 | out 0x21,al |
262 | out 0x21,al |
261 | call pic_delay |
- | |
262 | out 0xA1,al |
263 | out 0xA1,al |
263 | call pic_delay |
- | |
264 | 264 | ||
265 | call IRQ_mask_all |
- | |
266 | cli |
265 | call IRQ_mask_all |
267 | ; mov dword[irq_type_to_set], IRQ_TYPE_PIC |
266 | ; mov dword[irq_type_to_set], IRQ_TYPE_PIC |
268 | ret |
267 | ret |
269 | 268 | ||
270 | ; ----------------------------------------- |
269 | ; ----------------------------------------- |
271 | pic_delay: |
- | |
272 | jmp pdl1 |
- | |
273 | pdl1: ret |
- | |
274 | - | ||
275 | ; ----------------------------------------- |
- | |
276 | ; TIMER SET TO 1/100 S |
270 | ; TIMER SET TO 1/100 S |
277 | PIT_init: |
271 | PIT_init: |
278 | mov al,0x34 ; set to 100Hz |
272 | mov al,0x34 ; set to 100Hz |
279 | out 0x43,al |
273 | out 0x43,al |
280 | mov al,0x9b ; lsb 1193180 / 1193 |
274 | mov al,0x9b ; lsb 1193180 / 1193 |
281 | out 0x40,al |
275 | out 0x40,al |
282 | mov al,0x2e ; msb |
276 | mov al,0x2e ; msb |
283 | out 0x40,al |
277 | out 0x40,al |
284 | ret |
278 | ret |
285 | 279 | ||
286 | ; ----------------------------------------- |
280 | ; ----------------------------------------- |
287 | unmask_timer: |
281 | unmask_timer: |
288 | test dword[APIC], 0xffffffff |
282 | test dword[APIC], 0xffffffff |
289 | jnz @f |
283 | jnz @f |
290 | stdcall enable_irq, 0 |
284 | stdcall enable_irq, 0 |
291 | ret |
285 | ret |
292 | @@: |
286 | @@: |
293 | ; use PIT |
287 | ; use PIT |
294 | ; in some systems PIT no connected to IOAPIC |
288 | ; in some systems PIT no connected to IOAPIC |
295 | ; mov eax, 0x14 |
289 | ; mov eax, 0x14 |
296 | ; call IOAPIC_read |
290 | ; call IOAPIC_read |
297 | ; mov ah, 0x09 ; Delivery Mode: Lowest Priority, Destination Mode: Logical |
291 | ; mov ah, 0x09 ; Delivery Mode: Lowest Priority, Destination Mode: Logical |
298 | ; mov al, 0x20 |
292 | ; mov al, 0x20 |
299 | ; or eax, 0x10000 ; Mask Interrupt |
293 | ; or eax, 0x10000 ; Mask Interrupt |
300 | ; mov ebx, eax |
294 | ; mov ebx, eax |
301 | ; mov eax, 0x14 |
295 | ; mov eax, 0x14 |
302 | ; call IOAPIC_write |
296 | ; call IOAPIC_write |
303 | ; stdcall enable_irq, 2 |
297 | ; stdcall enable_irq, 2 |
304 | ; ret |
298 | ; ret |
305 | 299 | ||
306 | ; use LAPIC timer |
300 | ; use LAPIC timer |
307 | mov esi, [LAPIC_BASE] |
301 | mov esi, [LAPIC_BASE] |
308 | mov eax, [esi + APIC_LVT_timer] |
302 | mov eax, [esi + APIC_LVT_timer] |
309 | and eax, 0xfffeffff |
303 | and eax, 0xfffeffff |
310 | mov [esi + APIC_LVT_timer], eax |
304 | mov [esi + APIC_LVT_timer], eax |
311 | ret |
305 | ret |
312 | 306 | ||
313 | ; ----------------------------------------- |
307 | ; ----------------------------------------- |
314 | ; Disable all IRQ |
308 | ; Disable all IRQ |
315 | IRQ_mask_all: |
309 | IRQ_mask_all: |
316 | test dword[APIC], 0xffffffff |
310 | test dword[APIC], 0xffffffff |
317 | jnz .APIC |
311 | jnz .APIC |
318 | mov al, 0xFF |
312 | mov al, 0xFF |
319 | out 0x21, al |
313 | out 0x21, al |
320 | out 0xA1, al |
314 | out 0xA1, al |
321 | mov ecx,0x1000 |
315 | mov ecx,0x1000 |
322 | cld |
- | |
323 | @@: call pic_delay |
- | |
324 | loop @b |
- | |
325 | ret |
316 | ret |
326 | .APIC: |
317 | .APIC: |
327 | mov ecx, [IRQ_COUNT] |
318 | mov ecx, [IRQ_COUNT] |
328 | mov eax, 0x10 |
319 | mov eax, 0x10 |
- | 320 | @@: |
|
329 | @@: mov ebx, eax |
321 | mov ebx, eax |
330 | call IOAPIC_read |
322 | call IOAPIC_read |
331 | or eax, 0x10000 ; bit 16 |
323 | or eax, 0x10000 ; bit 16 |
332 | xchg eax, ebx |
324 | xchg eax, ebx |
333 | call IOAPIC_write |
325 | call IOAPIC_write |
334 | inc eax |
326 | inc eax |
335 | inc eax |
327 | inc eax |
336 | loop @b |
328 | loop @b |
337 | ret |
329 | ret |
- | 330 | ||
338 | ; ----------------------------------------- |
331 | ; ----------------------------------------- |
339 | ; End Of Interrupt |
332 | ; End Of Interrupt |
340 | ; cl - IRQ number |
333 | ; cl - IRQ number |
341 | align 16 |
334 | align 16 |
342 | irq_eoi: ; __fastcall |
335 | irq_eoi: ; __fastcall |
343 | test dword[APIC], 0xffffffff |
336 | test dword[APIC], 0xffffffff |
344 | jnz .APIC |
337 | jnz .APIC |
- | 338 | ||
345 | cmp cl, 8 |
339 | cmp cl, 8 |
346 | mov al, 0x20 |
340 | mov al, 0x20 |
347 | jb @f |
341 | jb @f |
348 | out 0xa0, al |
342 | out 0xa0, al |
349 | @@: |
343 | @@: |
350 | out 0x20, al |
344 | out 0x20, al |
351 | ret |
345 | ret |
352 | 346 | ||
353 | .APIC: |
347 | .APIC: |
354 | mov eax, [LAPIC_BASE] |
348 | mov eax, [LAPIC_BASE] |
355 | mov dword [eax + APIC_EOI], 0 ; EOI |
349 | mov dword [eax + APIC_EOI], 0 ; EOI |
356 | ret |
350 | ret |
357 | 351 | ||
358 | ; ----------------------------------------- |
352 | ; ----------------------------------------- |
359 | ; from dll.inc |
353 | ; from dll.inc |
360 | align 4 |
354 | align 4 |
361 | proc enable_irq stdcall, irq_line:dword |
355 | proc enable_irq stdcall, irq_line:dword |
362 | mov ebx, [irq_line] |
356 | mov ebx, [irq_line] |
363 | test dword[APIC], 0xffffffff |
357 | test dword[APIC], 0xffffffff |
364 | jnz .APIC |
358 | jnz .APIC |
- | 359 | ||
365 | mov edx, 0x21 |
360 | mov edx, 0x21 |
366 | cmp ebx, 8 |
361 | cmp ebx, 8 |
367 | jb @F |
362 | jb @F |
- | 363 | ||
368 | mov edx, 0xA1 |
364 | mov edx, 0xA1 |
369 | sub ebx,8 |
365 | sub ebx,8 |
370 | @@: |
366 | @@: |
371 | in al,dx |
367 | in al,dx |
372 | btr eax, ebx |
368 | btr eax, ebx |
373 | out dx, al |
369 | out dx, al |
374 | ret |
370 | ret |
375 | .APIC: |
371 | .APIC: |
376 | shl ebx, 1 |
372 | shl ebx, 1 |
377 | add ebx, 0x10 |
373 | add ebx, 0x10 |
378 | mov eax, ebx |
374 | mov eax, ebx |
379 | call IOAPIC_read |
375 | call IOAPIC_read |
380 | and eax, 0xfffeffff ; bit 16 |
376 | and eax, 0xfffeffff ; bit 16 |
381 | xchg eax, ebx |
377 | xchg eax, ebx |
382 | call IOAPIC_write |
378 | call IOAPIC_write |
383 | ret |
379 | ret |
384 | endp |
380 | endp |
385 | 381 | ||
386 | 382 | ||
387 | 383 | ||
388 | ; IRQ_TYPE_DISABLE equ 0 |
384 | ; IRQ_TYPE_DISABLE equ 0 |
389 | ; IRQ_TYPE_PIC equ 1 |
385 | ; IRQ_TYPE_PIC equ 1 |
390 | ; IRQ_TYPE_APIC equ 2 |
386 | ; IRQ_TYPE_APIC equ 2 |
391 | 387 | ||
392 | ; uglobal |
388 | ; uglobal |
393 | ; irq_type_to_set rd 1 |
389 | ; irq_type_to_set rd 1 |
394 | ; irq_types rd IRQ_RESERVE |
390 | ; irq_types rd IRQ_RESERVE |
395 | ; endg |
391 | ; endg |
396 | 392 | ||
397 | ; ----------------------------------------- |
393 | ; ----------------------------------------- |
398 | ; End Of Interrupt |
394 | ; End Of Interrupt |
399 | ; al - IRQ number |
395 | ; al - IRQ number |
400 | ; align 16 |
396 | ; align 16 |
401 | ; IRQ_EOI: |
397 | ; IRQ_EOI: |
402 | ; movzx eax, al |
398 | ; movzx eax, al |
403 | ; cmp dword[irq_types + eax * 4], IRQ_TYPE_APIC |
399 | ; cmp dword[irq_types + eax * 4], IRQ_TYPE_APIC |
404 | ; jne @f |
400 | ; jne @f |
405 | ; mov eax, [LAPIC_BASE] |
401 | ; mov eax, [LAPIC_BASE] |
406 | ; mov dword [eax + APIC_EOI], 0 ; EOI |
402 | ; mov dword [eax + APIC_EOI], 0 ; EOI |
407 | ; ret |
403 | ; ret |
408 | ; @@: |
404 | ; @@: |
409 | ; cmp al, 8 |
405 | ; cmp al, 8 |
410 | ; mov al, 0x20 |
406 | ; mov al, 0x20 |
411 | ; jb @f |
407 | ; jb @f |
412 | ; out 0xa0, al |
408 | ; out 0xa0, al |
413 | ; @@: out 0x20, al |
409 | ; @@: out 0x20, al |
414 | ; ret |
410 | ; ret |
415 | 411 | ||
416 | ; align 4 |
412 | ; align 4 |
417 | ; proc enable_irq stdcall, irq_line:dword |
413 | ; proc enable_irq stdcall, irq_line:dword |
418 | ; cmp dword[irq_type_to_set], IRQ_TYPE_APIC |
414 | ; cmp dword[irq_type_to_set], IRQ_TYPE_APIC |
419 | ; jne @f |
415 | ; jne @f |
420 | ; stdcall APIC_enable_irq, [irq_line] |
416 | ; stdcall APIC_enable_irq, [irq_line] |
421 | ; ret |
417 | ; ret |
422 | ; @@: stdcall PIC_enable_irq, [irq_line] |
418 | ; @@: stdcall PIC_enable_irq, [irq_line] |
423 | ; ret |
419 | ; ret |
424 | ; endp |
420 | ; endp |
425 | 421 | ||
426 | ; align 4 |
422 | ; align 4 |
427 | ; proc disable_irq stdcall, irq_line:dword |
423 | ; proc disable_irq stdcall, irq_line:dword |
428 | ; push eax |
424 | ; push eax |
429 | ; mov eax, [irq_line] |
425 | ; mov eax, [irq_line] |
430 | ; cmp dword[irq_types + eax * 4], IRQ_TYPE_APIC |
426 | ; cmp dword[irq_types + eax * 4], IRQ_TYPE_APIC |
431 | ; jne @f |
427 | ; jne @f |
432 | ; stdcall APIC_disable_irq, eax |
428 | ; stdcall APIC_disable_irq, eax |
433 | ; pop eax |
429 | ; pop eax |
434 | ; ret |
430 | ; ret |
435 | ; @@: stdcall PIC_disable_irq, eax |
431 | ; @@: stdcall PIC_disable_irq, eax |
436 | ; pop eax |
432 | ; pop eax |
437 | ; ret |
433 | ; ret |
438 | ; endp |
434 | ; endp |
439 | 435 | ||
440 | ; align 4 |
436 | ; align 4 |
441 | ; proc PIC_enable_irq stdcall, irq_line:dword |
437 | ; proc PIC_enable_irq stdcall, irq_line:dword |
442 | ; pusha |
438 | ; pusha |
443 | ; mov ebx, [irq_line] |
439 | ; mov ebx, [irq_line] |
444 | ; mov eax, [irq_types + ebx * 4] |
440 | ; mov eax, [irq_types + ebx * 4] |
445 | ; cmp eax, IRQ_TYPE_DISABLE |
441 | ; cmp eax, IRQ_TYPE_DISABLE |
446 | ; je @f |
442 | ; je @f |
447 | ; cmp eax, IRQ_TYPE_PIC |
443 | ; cmp eax, IRQ_TYPE_PIC |
448 | ; je @f |
444 | ; je @f |
449 | ; stdcall disable_irq, ebx |
445 | ; stdcall disable_irq, ebx |
450 | ; @@: mov dword[irq_types + ebx * 4], IRQ_TYPE_PIC |
446 | ; @@: mov dword[irq_types + ebx * 4], IRQ_TYPE_PIC |
451 | ; mov edx, 0x21 |
447 | ; mov edx, 0x21 |
452 | ; cmp ebx, 8 |
448 | ; cmp ebx, 8 |
453 | ; jb @F |
449 | ; jb @F |
454 | ; mov edx, 0xA1 |
450 | ; mov edx, 0xA1 |
455 | ; sub ebx,8 |
451 | ; sub ebx,8 |
456 | ; @@: in al,dx |
452 | ; @@: in al,dx |
457 | ; btr eax, ebx |
453 | ; btr eax, ebx |
458 | ; out dx, al |
454 | ; out dx, al |
459 | ; popa |
455 | ; popa |
460 | ; ret |
456 | ; ret |
461 | ; endp |
457 | ; endp |
462 | 458 | ||
463 | ; align 4 |
459 | ; align 4 |
464 | ; proc PIC_disable_irq stdcall, irq_line:dword |
460 | ; proc PIC_disable_irq stdcall, irq_line:dword |
465 | ; pusha |
461 | ; pusha |
466 | ; mov ebx, [irq_line] |
462 | ; mov ebx, [irq_line] |
467 | ; mov dword[irq_types + ebx * 4], IRQ_TYPE_DISABLE |
463 | ; mov dword[irq_types + ebx * 4], IRQ_TYPE_DISABLE |
468 | ; mov edx, 0x21 |
464 | ; mov edx, 0x21 |
469 | ; cmp ebx, 8 |
465 | ; cmp ebx, 8 |
470 | ; jb @F |
466 | ; jb @F |
471 | ; mov edx, 0xA1 |
467 | ; mov edx, 0xA1 |
472 | ; sub ebx,8 |
468 | ; sub ebx,8 |
473 | ; @@: in al,dx |
469 | ; @@: in al,dx |
474 | ; bts eax, ebx |
470 | ; bts eax, ebx |
475 | ; out dx, al |
471 | ; out dx, al |
476 | ; popa |
472 | ; popa |
477 | ; ret |
473 | ; ret |
478 | ; endp |
474 | ; endp |
479 | 475 | ||
480 | ; align 4 |
476 | ; align 4 |
481 | ; proc APIC_enable_irq stdcall, irq_line:dword |
477 | ; proc APIC_enable_irq stdcall, irq_line:dword |
482 | ; pusha |
478 | ; pusha |
483 | ; mov ebx, [irq_line] |
479 | ; mov ebx, [irq_line] |
484 | ; mov eax, [irq_types + ebx * 4] |
480 | ; mov eax, [irq_types + ebx * 4] |
485 | ; cmp eax, IRQ_TYPE_DISABLE |
481 | ; cmp eax, IRQ_TYPE_DISABLE |
486 | ; je @f |
482 | ; je @f |
487 | ; cmp eax, IRQ_TYPE_APIC |
483 | ; cmp eax, IRQ_TYPE_APIC |
488 | ; je @f |
484 | ; je @f |
489 | ; stdcall disable_irq, ebx |
485 | ; stdcall disable_irq, ebx |
490 | ; @@: mov dword[irq_types + ebx * 4], IRQ_TYPE_APIC |
486 | ; @@: mov dword[irq_types + ebx * 4], IRQ_TYPE_APIC |
491 | ; shl ebx, 1 |
487 | ; shl ebx, 1 |
492 | ; add ebx, 0x10 |
488 | ; add ebx, 0x10 |
493 | ; mov eax, ebx |
489 | ; mov eax, ebx |
494 | ; call IOAPIC_read |
490 | ; call IOAPIC_read |
495 | ; and eax, 0xfffeffff ; bit 16 |
491 | ; and eax, 0xfffeffff ; bit 16 |
496 | ; xchg eax, ebx |
492 | ; xchg eax, ebx |
497 | ; call IOAPIC_write |
493 | ; call IOAPIC_write |
498 | ; popa |
494 | ; popa |
499 | ; ret |
495 | ; ret |
500 | ; endp |
496 | ; endp |
501 | 497 | ||
502 | ; align 4 |
498 | ; align 4 |
503 | ; proc APIC_disable_irq stdcall, irq_line:dword |
499 | ; proc APIC_disable_irq stdcall, irq_line:dword |
504 | ; pusha |
500 | ; pusha |
505 | ; mov ebx, [irq_line] |
501 | ; mov ebx, [irq_line] |
506 | ; mov dword[irq_types + ebx * 4], IRQ_TYPE_DISABLE |
502 | ; mov dword[irq_types + ebx * 4], IRQ_TYPE_DISABLE |
507 | ; shl ebx, 1 |
503 | ; shl ebx, 1 |
508 | ; add ebx, 0x10 |
504 | ; add ebx, 0x10 |
509 | ; mov eax, ebx |
505 | ; mov eax, ebx |
510 | ; call IOAPIC_read |
506 | ; call IOAPIC_read |
511 | ; or eax, 0x10000 |
507 | ; or eax, 0x10000 |
512 | ; xchg eax, ebx |
508 | ; xchg eax, ebx |
513 | ; call IOAPIC_write |
509 | ; call IOAPIC_write |
514 | ; popa |
510 | ; popa |
515 | ; ret |
511 | ; ret |
516 | ; endp><><<> |
512 | ; endp><><<> |