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