Rev 2443 | Rev 3320 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2443 | Rev 2455 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2012. 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 | 8 | ||
9 | iglobal |
9 | iglobal |
10 | IRQ_COUNT dd 24 |
10 | IRQ_COUNT dd 24 |
11 | endg |
11 | endg |
12 | 12 | ||
13 | uglobal |
13 | uglobal |
14 | irq_mode rd 1 |
14 | irq_mode rd 1 |
15 | IOAPIC_base rd 1 |
15 | IOAPIC_base rd 1 |
16 | LAPIC_BASE rd 1 |
16 | LAPIC_BASE rd 1 |
17 | endg |
17 | endg |
18 | 18 | ||
19 | APIC_ID equ 0x20 |
19 | APIC_ID equ 0x20 |
20 | APIC_TPR equ 0x80 |
20 | APIC_TPR equ 0x80 |
21 | APIC_EOI equ 0xb0 |
21 | APIC_EOI equ 0xb0 |
22 | APIC_LDR equ 0xd0 |
22 | APIC_LDR equ 0xd0 |
23 | APIC_DFR equ 0xe0 |
23 | APIC_DFR equ 0xe0 |
24 | APIC_SVR equ 0xf0 |
24 | APIC_SVR equ 0xf0 |
25 | APIC_ISR equ 0x100 |
25 | APIC_ISR equ 0x100 |
26 | APIC_ESR equ 0x280 |
26 | APIC_ESR equ 0x280 |
27 | APIC_ICRL equ 0x300 |
27 | APIC_ICRL equ 0x300 |
28 | APIC_ICRH equ 0x310 |
28 | APIC_ICRH equ 0x310 |
29 | APIC_LVT_LINT0 equ 0x350 |
29 | APIC_LVT_LINT0 equ 0x350 |
30 | APIC_LVT_LINT1 equ 0x360 |
30 | APIC_LVT_LINT1 equ 0x360 |
31 | APIC_LVT_err equ 0x370 |
31 | APIC_LVT_err equ 0x370 |
32 | 32 | ||
33 | ; APIC timer |
33 | ; APIC timer |
34 | APIC_LVT_timer equ 0x320 |
34 | APIC_LVT_timer equ 0x320 |
35 | APIC_timer_div equ 0x3e0 |
35 | APIC_timer_div equ 0x3e0 |
36 | APIC_timer_init equ 0x380 |
36 | APIC_timer_init equ 0x380 |
37 | APIC_timer_cur equ 0x390 |
37 | APIC_timer_cur equ 0x390 |
38 | ; IOAPIC |
38 | ; IOAPIC |
39 | IOAPIC_ID equ 0x0 |
39 | IOAPIC_ID equ 0x0 |
40 | IOAPIC_VER equ 0x1 |
40 | IOAPIC_VER equ 0x1 |
41 | IOAPIC_ARB equ 0x2 |
41 | IOAPIC_ARB equ 0x2 |
42 | IOAPIC_REDTBL equ 0x10 |
42 | IOAPIC_REDTBL equ 0x10 |
43 | 43 | ||
44 | align 4 |
44 | align 4 |
45 | APIC_init: |
45 | APIC_init: |
46 | mov [irq_mode], IRQ_PIC |
46 | mov [irq_mode], IRQ_PIC |
47 | 47 | ||
48 | cmp [acpi_ioapic_base], 0 |
48 | cmp [acpi_ioapic_base], 0 |
49 | jz .no_apic |
49 | jz .no_apic |
50 | 50 | ||
51 | cmp [acpi_lapic_base], 0 |
51 | cmp [acpi_lapic_base], 0 |
52 | jz .no_apic |
52 | jz .no_apic |
53 | 53 | ||
54 | stdcall load_file, dev_data_path |
54 | stdcall load_file, dev_data_path |
55 | test eax, eax |
55 | test eax, eax |
56 | jz .no_apic |
56 | jz .no_apic |
57 | 57 | ||
58 | mov [acpi_dev_data], eax |
58 | mov [acpi_dev_data], eax |
59 | mov [acpi_dev_size], ebx |
59 | mov [acpi_dev_size], ebx |
60 | 60 | ||
61 | call IRQ_mask_all |
61 | call IRQ_mask_all |
62 | 62 | ||
63 | ; IOAPIC init |
63 | ; IOAPIC init |
64 | stdcall map_io_mem, [acpi_ioapic_base], 0x20, PG_SW+PG_NOCACHE |
64 | stdcall map_io_mem, [acpi_ioapic_base], 0x20, PG_SW+PG_NOCACHE |
65 | mov [IOAPIC_base], eax |
65 | mov [IOAPIC_base], eax |
66 | 66 | ||
67 | mov eax, IOAPIC_VER |
67 | mov eax, IOAPIC_VER |
68 | call IOAPIC_read |
68 | call IOAPIC_read |
69 | shr eax, 16 |
69 | shr eax, 16 |
70 | inc al |
70 | inc al |
71 | movzx eax, al |
71 | movzx eax, al |
72 | cmp al, IRQ_RESERVED |
72 | cmp al, IRQ_RESERVED |
73 | jbe @f |
73 | jbe @f |
74 | 74 | ||
75 | mov al, IRQ_RESERVED |
75 | mov al, IRQ_RESERVED |
76 | @@: |
76 | @@: |
77 | mov [IRQ_COUNT], eax |
77 | mov [IRQ_COUNT], eax |
78 | 78 | ||
79 | ; Reroute IOAPIC & mask all interrupts |
79 | ; Reroute IOAPIC & mask all interrupts |
80 | xor ecx, ecx |
80 | xor ecx, ecx |
81 | mov eax, IOAPIC_REDTBL |
81 | mov eax, IOAPIC_REDTBL |
82 | @@: |
82 | @@: |
83 | mov ebx, eax |
83 | mov ebx, eax |
84 | call IOAPIC_read |
84 | call IOAPIC_read |
85 | mov ah, 0x09; Delivery Mode: Lowest Priority, Destination Mode: Logical |
85 | mov ah, 0x09; Delivery Mode: Lowest Priority, Destination Mode: Logical |
86 | mov al, cl |
86 | mov al, cl |
87 | add al, 0x20; vector |
87 | add al, 0x20; vector |
88 | or eax, 0x10000; Mask Interrupt |
88 | or eax, 0x10000; Mask Interrupt |
89 | cmp ecx, 16 |
89 | cmp ecx, 16 |
90 | jb .set |
90 | jb .set |
91 | 91 | ||
92 | or eax, 0xa000;<<< level-triggered active-low for IRQ16+ |
92 | or eax, 0xa000;<<< level-triggered active-low for IRQ16+ |
93 | .set: |
93 | .set: |
94 | xchg eax, ebx |
94 | xchg eax, ebx |
95 | call IOAPIC_write |
95 | call IOAPIC_write |
96 | inc eax |
96 | inc eax |
97 | mov ebx, eax |
97 | mov ebx, eax |
98 | call IOAPIC_read |
98 | call IOAPIC_read |
99 | or eax, 0xff000000; Destination Field |
99 | or eax, 0xff000000; Destination Field |
100 | xchg eax, ebx |
100 | xchg eax, ebx |
101 | call IOAPIC_write |
101 | call IOAPIC_write |
102 | inc eax |
102 | inc eax |
103 | inc ecx |
103 | inc ecx |
104 | cmp ecx, [IRQ_COUNT] |
104 | cmp ecx, [IRQ_COUNT] |
105 | jb @b |
105 | jb @b |
106 | 106 | ||
107 | call LAPIC_init |
107 | call LAPIC_init |
108 | 108 | ||
109 | mov [irq_mode], IRQ_APIC |
109 | mov [irq_mode], IRQ_APIC |
110 | 110 | ||
111 | mov al, 0x70 |
111 | mov al, 0x70 |
112 | out 0x22, al |
112 | out 0x22, al |
113 | mov al, 1 |
113 | mov al, 1 |
114 | out 0x23, al |
114 | out 0x23, al |
115 | 115 | ||
116 | call pci_irq_fixup |
116 | call pci_irq_fixup |
117 | .no_apic: |
117 | .no_apic: |
118 | 118 | ||
119 | ret |
119 | ret |
120 | 120 | ||
121 | ;=========================================================== |
121 | ;=========================================================== |
122 | align 4 |
122 | align 4 |
123 | LAPIC_init: |
123 | LAPIC_init: |
124 | 124 | ||
125 | cmp [LAPIC_BASE], 0 |
125 | cmp [LAPIC_BASE], 0 |
126 | jne .done |
126 | jne .done |
127 | 127 | ||
128 | stdcall map_io_mem, [acpi_lapic_base], 0x1000, PG_SW+PG_NOCACHE |
128 | stdcall map_io_mem, [acpi_lapic_base], 0x1000, PG_SW+PG_NOCACHE |
129 | mov [LAPIC_BASE], eax |
129 | mov [LAPIC_BASE], eax |
130 | mov esi, eax |
130 | mov esi, eax |
131 | 131 | ||
132 | ; Program Destination Format Register for Flat mode. |
132 | ; Program Destination Format Register for Flat mode. |
133 | mov eax, [esi + APIC_DFR] |
133 | mov eax, [esi + APIC_DFR] |
134 | or eax, 0xf0000000 |
134 | or eax, 0xf0000000 |
135 | mov [esi + APIC_DFR], eax |
135 | mov [esi + APIC_DFR], eax |
136 | 136 | ||
137 | ; Program Logical Destination Register. |
137 | ; Program Logical Destination Register. |
138 | mov eax, [esi + APIC_LDR] |
138 | mov eax, [esi + APIC_LDR] |
139 | ;and eax, 0xff000000 |
139 | ;and eax, 0xff000000 |
140 | and eax, 0x00ffffff |
140 | and eax, 0x00ffffff |
141 | or eax, 0x01000000;!!!!!!!!!!!! |
141 | or eax, 0x01000000;!!!!!!!!!!!! |
142 | mov [esi + APIC_LDR], eax |
142 | mov [esi + APIC_LDR], eax |
143 | 143 | ||
144 | ; Task Priority Register initialization. |
144 | ; Task Priority Register initialization. |
145 | mov eax, [esi + APIC_TPR] |
145 | mov eax, [esi + APIC_TPR] |
146 | and eax, 0xffffff00 |
146 | and eax, 0xffffff00 |
147 | mov [esi + APIC_TPR], eax |
147 | mov [esi + APIC_TPR], eax |
148 | 148 | ||
149 | ; Flush the queue |
149 | ; Flush the queue |
150 | mov edx, 0 |
150 | mov edx, 0 |
151 | .nxt2: |
151 | .nxt2: |
152 | mov ecx, 32 |
152 | mov ecx, 32 |
153 | mov eax, [esi + APIC_ISR + edx] |
153 | mov eax, [esi + APIC_ISR + edx] |
154 | .nxt: |
154 | .nxt: |
155 | shr eax, 1 |
155 | shr eax, 1 |
156 | jnc @f |
156 | jnc @f |
157 | mov dword [esi + APIC_EOI], 0; EOI |
157 | mov dword [esi + APIC_EOI], 0; EOI |
158 | @@: |
158 | @@: |
159 | loop .nxt |
159 | loop .nxt |
160 | 160 | ||
161 | add edx, 0x10 |
161 | add edx, 0x10 |
162 | cmp edx, 0x170 |
162 | cmp edx, 0x170 |
163 | jbe .nxt2 |
163 | jbe .nxt2 |
164 | 164 | ||
165 | ; Spurious-Interrupt Vector Register initialization. |
165 | ; Spurious-Interrupt Vector Register initialization. |
166 | mov eax, [esi + APIC_SVR] |
166 | mov eax, [esi + APIC_SVR] |
167 | or eax, 0x1ff |
167 | or eax, 0x1ff |
168 | and eax, 0xfffffdff |
168 | and eax, 0xfffffdff |
169 | mov [esi + APIC_SVR], eax |
169 | mov [esi + APIC_SVR], eax |
170 | 170 | ||
171 | ; Initialize LVT LINT0 register. (INTR) |
171 | ; Initialize LVT LINT0 register. (INTR) |
172 | mov eax, 0x00700 |
172 | mov eax, 0x00700 |
173 | ; mov eax, 0x10700 |
173 | ; mov eax, 0x10700 |
174 | mov [esi + APIC_LVT_LINT0], eax |
174 | mov [esi + APIC_LVT_LINT0], eax |
175 | 175 | ||
176 | ; Initialize LVT LINT1 register. (NMI) |
176 | ; Initialize LVT LINT1 register. (NMI) |
177 | mov eax, 0x00400 |
177 | mov eax, 0x00400 |
178 | mov [esi + APIC_LVT_LINT1], eax |
178 | mov [esi + APIC_LVT_LINT1], eax |
179 | 179 | ||
180 | ; Initialize LVT Error register. |
180 | ; Initialize LVT Error register. |
181 | mov eax, [esi + APIC_LVT_err] |
181 | mov eax, [esi + APIC_LVT_err] |
182 | or eax, 0x10000; bit 16 |
182 | or eax, 0x10000; bit 16 |
183 | mov [esi + APIC_LVT_err], eax |
183 | mov [esi + APIC_LVT_err], eax |
184 | 184 | ||
185 | ; LAPIC timer |
185 | ; LAPIC timer |
186 | ; pre init |
186 | ; pre init |
187 | mov dword[esi + APIC_timer_div], 1011b; 1 |
187 | mov dword[esi + APIC_timer_div], 1011b; 1 |
188 | mov dword[esi + APIC_timer_init], 0xffffffff; max val |
188 | mov dword[esi + APIC_timer_init], 0xffffffff; max val |
189 | push esi |
189 | push esi |
190 | mov esi, 640 ; wait 0.64 sec |
190 | mov esi, 640 ; wait 0.64 sec |
191 | call delay_ms |
191 | call delay_ms |
192 | pop esi |
192 | pop esi |
193 | mov eax, [esi + APIC_timer_cur]; read current tick couner |
193 | mov eax, [esi + APIC_timer_cur]; read current tick couner |
194 | xor eax, 0xffffffff ; eax = 0xffffffff - eax |
194 | xor eax, 0xffffffff ; eax = 0xffffffff - eax |
195 | shr eax, 6 ; eax /= 64; APIC ticks per 0.01 sec |
195 | shr eax, 6 ; eax /= 64; APIC ticks per 0.01 sec |
196 | 196 | ||
197 | ; Start (every 0.01 sec) |
197 | ; Start (every 0.01 sec) |
198 | mov dword[esi + APIC_LVT_timer], 0x30020; periodic int 0x20 |
198 | mov dword[esi + APIC_LVT_timer], 0x30020; periodic int 0x20 |
199 | mov dword[esi + APIC_timer_init], eax |
199 | mov dword[esi + APIC_timer_init], eax |
200 | 200 | ||
201 | .done: |
201 | .done: |
202 | ret |
202 | ret |
203 | 203 | ||
204 | ;=========================================================== |
204 | ;=========================================================== |
205 | ; IOAPIC implementation |
205 | ; IOAPIC implementation |
206 | align 4 |
206 | align 4 |
207 | IOAPIC_read: |
207 | IOAPIC_read: |
208 | ; in : EAX - IOAPIC register |
208 | ; in : EAX - IOAPIC register |
209 | ; out: EAX - readed value |
209 | ; out: EAX - readed value |
210 | push esi |
210 | push esi |
211 | mov esi, [IOAPIC_base] |
211 | mov esi, [IOAPIC_base] |
212 | mov [esi], eax |
212 | mov [esi], eax |
213 | mov eax, [esi + 0x10] |
213 | mov eax, [esi + 0x10] |
214 | pop esi |
214 | pop esi |
215 | ret |
215 | ret |
216 | 216 | ||
217 | align 4 |
217 | align 4 |
218 | IOAPIC_write: |
218 | IOAPIC_write: |
219 | ; in : EAX - IOAPIC register |
219 | ; in : EAX - IOAPIC register |
220 | ; EBX - value |
220 | ; EBX - value |
221 | ; out: none |
221 | ; out: none |
222 | push esi |
222 | push esi |
223 | mov esi, [IOAPIC_base] |
223 | mov esi, [IOAPIC_base] |
224 | mov [esi], eax |
224 | mov [esi], eax |
225 | mov [esi + 0x10], ebx |
225 | mov [esi + 0x10], ebx |
226 | pop esi |
226 | pop esi |
227 | ret |
227 | ret |
228 | ;=========================================================== |
228 | ;=========================================================== |
229 | ; Remap all IRQ to 0x20+ Vectors |
229 | ; Remap all IRQ to 0x20+ Vectors |
230 | ; IRQ0 to vector 0x20, IRQ1 to vector 0x21.... |
230 | ; IRQ0 to vector 0x20, IRQ1 to vector 0x21.... |
231 | align 4 |
231 | align 4 |
232 | PIC_init: |
232 | PIC_init: |
233 | cli |
233 | cli |
234 | mov al, 0x11 ; icw4, edge triggered |
234 | mov al, 0x11 ; icw4, edge triggered |
235 | out 0x20, al |
235 | out 0x20, al |
236 | out 0xA0, al |
236 | out 0xA0, al |
237 | 237 | ||
238 | mov al, 0x20 ; generate 0x20 + |
238 | mov al, 0x20 ; generate 0x20 + |
239 | out 0x21, al |
239 | out 0x21, al |
240 | mov al, 0x28 ; generate 0x28 + |
240 | mov al, 0x28 ; generate 0x28 + |
241 | out 0xA1, al |
241 | out 0xA1, al |
242 | 242 | ||
243 | mov al, 0x04 ; slave at irq2 |
243 | mov al, 0x04 ; slave at irq2 |
244 | out 0x21, al |
244 | out 0x21, al |
245 | mov al, 0x02 ; at irq9 |
245 | mov al, 0x02 ; at irq9 |
246 | out 0xA1, al |
246 | out 0xA1, al |
247 | 247 | ||
248 | mov al, 0x01 ; 8086 mode |
248 | mov al, 0x01 ; 8086 mode |
249 | out 0x21, al |
249 | out 0x21, al |
250 | out 0xA1, al |
250 | out 0xA1, al |
251 | 251 | ||
252 | call IRQ_mask_all |
252 | call IRQ_mask_all |
253 | ; mov dword[irq_type_to_set], IRQ_TYPE_PIC |
253 | ; mov dword[irq_type_to_set], IRQ_TYPE_PIC |
254 | ret |
254 | ret |
255 | 255 | ||
256 | ; ----------------------------------------- |
256 | ; ----------------------------------------- |
257 | ; TIMER SET TO 1/100 S |
257 | ; TIMER SET TO 1/100 S |
258 | align 4 |
258 | align 4 |
259 | PIT_init: |
259 | PIT_init: |
260 | mov al, 0x34 ; set to 100Hz |
260 | mov al, 0x34 ; set to 100Hz |
261 | out 0x43, al |
261 | out 0x43, al |
262 | mov al, 0x9b ; lsb 1193180 / 1193 |
262 | mov al, 0x9b ; lsb 1193180 / 1193 |
263 | out 0x40, al |
263 | out 0x40, al |
264 | mov al, 0x2e ; msb |
264 | mov al, 0x2e ; msb |
265 | out 0x40, al |
265 | out 0x40, al |
266 | ret |
266 | ret |
267 | 267 | ||
268 | ; ----------------------------------------- |
268 | ; ----------------------------------------- |
269 | align 4 |
269 | align 4 |
270 | unmask_timer: |
270 | unmask_timer: |
271 | cmp [irq_mode], IRQ_APIC |
271 | cmp [irq_mode], IRQ_APIC |
272 | je @f |
272 | je @f |
273 | 273 | ||
274 | stdcall enable_irq, 0 |
274 | stdcall enable_irq, 0 |
275 | ret |
275 | ret |
276 | @@: |
276 | @@: |
277 | ; use PIT |
277 | ; use PIT |
278 | ; in some systems PIT no connected to IOAPIC |
278 | ; in some systems PIT no connected to IOAPIC |
279 | ; mov eax, 0x14 |
279 | ; mov eax, 0x14 |
280 | ; call IOAPIC_read |
280 | ; call IOAPIC_read |
281 | ; mov ah, 0x09 ; Delivery Mode: Lowest Priority, Destination Mode: Logical |
281 | ; mov ah, 0x09 ; Delivery Mode: Lowest Priority, Destination Mode: Logical |
282 | ; mov al, 0x20 |
282 | ; mov al, 0x20 |
283 | ; or eax, 0x10000 ; Mask Interrupt |
283 | ; or eax, 0x10000 ; Mask Interrupt |
284 | ; mov ebx, eax |
284 | ; mov ebx, eax |
285 | ; mov eax, 0x14 |
285 | ; mov eax, 0x14 |
286 | ; call IOAPIC_write |
286 | ; call IOAPIC_write |
287 | ; stdcall enable_irq, 2 |
287 | ; stdcall enable_irq, 2 |
288 | ; ret |
288 | ; ret |
289 | 289 | ||
290 | ; use LAPIC timer |
290 | ; use LAPIC timer |
291 | mov esi, [LAPIC_BASE] |
291 | mov esi, [LAPIC_BASE] |
292 | mov eax, [esi + APIC_LVT_timer] |
292 | mov eax, [esi + APIC_LVT_timer] |
293 | and eax, 0xfffeffff |
293 | and eax, 0xfffeffff |
294 | mov [esi + APIC_LVT_timer], eax |
294 | mov [esi + APIC_LVT_timer], eax |
295 | ret |
295 | ret |
296 | 296 | ||
297 | ; ----------------------------------------- |
297 | ; ----------------------------------------- |
298 | ; Disable all IRQ |
298 | ; Disable all IRQ |
299 | align 4 |
299 | align 4 |
300 | IRQ_mask_all: |
300 | IRQ_mask_all: |
301 | cmp [irq_mode], IRQ_APIC |
301 | cmp [irq_mode], IRQ_APIC |
302 | je .APIC |
302 | je .APIC |
303 | 303 | ||
304 | mov al, 0xFF |
304 | mov al, 0xFF |
305 | out 0x21, al |
305 | out 0x21, al |
306 | out 0xA1, al |
306 | out 0xA1, al |
307 | mov ecx, 0x1000 |
307 | mov ecx, 0x1000 |
308 | ret |
308 | ret |
309 | .APIC: |
309 | .APIC: |
310 | mov ecx, [IRQ_COUNT] |
310 | mov ecx, [IRQ_COUNT] |
311 | mov eax, 0x10 |
311 | mov eax, 0x10 |
312 | @@: |
312 | @@: |
313 | mov ebx, eax |
313 | mov ebx, eax |
314 | call IOAPIC_read |
314 | call IOAPIC_read |
315 | or eax, 0x10000; bit 16 |
315 | or eax, 0x10000; bit 16 |
316 | xchg eax, ebx |
316 | xchg eax, ebx |
317 | call IOAPIC_write |
317 | call IOAPIC_write |
318 | inc eax |
318 | inc eax |
319 | inc eax |
319 | inc eax |
320 | loop @b |
320 | loop @b |
321 | ret |
321 | ret |
322 | 322 | ||
323 | ; ----------------------------------------- |
323 | ; ----------------------------------------- |
324 | ; End Of Interrupt |
324 | ; End Of Interrupt |
325 | ; cl - IRQ number |
325 | ; cl - IRQ number |
326 | align 4 |
326 | align 4 |
327 | irq_eoi: ; __fastcall |
327 | irq_eoi: ; __fastcall |
328 | cmp [irq_mode], IRQ_APIC |
328 | cmp [irq_mode], IRQ_APIC |
329 | je .APIC |
329 | je .APIC |
330 | 330 | ||
331 | cmp cl, 8 |
331 | cmp cl, 8 |
332 | mov al, 0x20 |
332 | mov al, 0x20 |
333 | jb @f |
333 | jb @f |
334 | out 0xa0, al |
334 | out 0xa0, al |
335 | @@: |
335 | @@: |
336 | out 0x20, al |
336 | out 0x20, al |
337 | ret |
337 | ret |
338 | 338 | ||
339 | .APIC: |
339 | .APIC: |
340 | mov eax, [LAPIC_BASE] |
340 | mov eax, [LAPIC_BASE] |
341 | mov dword [eax + APIC_EOI], 0; EOI |
341 | mov dword [eax + APIC_EOI], 0; EOI |
342 | ret |
342 | ret |
343 | 343 | ||
344 | ; ----------------------------------------- |
344 | ; ----------------------------------------- |
345 | ; from dll.inc |
345 | ; from dll.inc |
346 | align 4 |
346 | align 4 |
347 | proc enable_irq stdcall, irq_line:dword |
347 | proc enable_irq stdcall, irq_line:dword |
348 | mov ebx, [irq_line] |
348 | mov ebx, [irq_line] |
349 | cmp [irq_mode], IRQ_APIC |
349 | cmp [irq_mode], IRQ_APIC |
350 | je .APIC |
350 | je .APIC |
351 | 351 | ||
352 | mov edx, 0x21 |
352 | mov edx, 0x21 |
353 | cmp ebx, 8 |
353 | cmp ebx, 8 |
354 | jb @F |
354 | jb @F |
355 | 355 | ||
356 | mov edx, 0xA1 |
356 | mov edx, 0xA1 |
357 | sub ebx, 8 |
357 | sub ebx, 8 |
358 | @@: |
358 | @@: |
359 | in al, dx |
359 | in al, dx |
360 | btr eax, ebx |
360 | btr eax, ebx |
361 | out dx, al |
361 | out dx, al |
362 | ret |
362 | ret |
363 | .APIC: |
363 | .APIC: |
364 | shl ebx, 1 |
364 | shl ebx, 1 |
365 | add ebx, 0x10 |
365 | add ebx, 0x10 |
366 | mov eax, ebx |
366 | mov eax, ebx |
367 | call IOAPIC_read |
367 | call IOAPIC_read |
368 | and eax, 0xfffeffff; bit 16 |
368 | and eax, 0xfffeffff; bit 16 |
369 | xchg eax, ebx |
369 | xchg eax, ebx |
370 | call IOAPIC_write |
370 | call IOAPIC_write |
371 | ret |
371 | ret |
372 | endp |
372 | endp |
373 | 373 | ||
374 | align 4 |
374 | align 4 |
375 | pci_irq_fixup: |
375 | pci_irq_fixup: |
376 | 376 | ||
377 | push ebp |
377 | push ebp |
378 | 378 | ||
379 | mov esi, [acpi_dev_data] |
379 | mov esi, [acpi_dev_data] |
380 | mov ebx, [acpi_dev_size] |
380 | mov ebx, [acpi_dev_size] |
381 | 381 | ||
382 | lea edi, [esi+ebx] |
382 | lea edi, [esi+ebx] |
383 | 383 | ||
384 | .iterate: |
384 | .iterate: |
385 | 385 | ||
386 | cmp esi, edi |
386 | cmp esi, edi |
387 | jae .done |
387 | jae .done |
388 | 388 | ||
389 | mov eax, [esi] |
389 | mov eax, [esi] |
390 | 390 | ||
391 | cmp eax, -1 |
391 | cmp eax, -1 |
392 | je .done |
392 | je .done |
393 | 393 | ||
394 | movzx ebx, al |
394 | movzx ebx, al |
395 | movzx ebp, ah |
395 | movzx ebp, ah |
396 | 396 | ||
397 | stdcall pci_read32, ebp, ebx, 0 |
397 | stdcall pci_read32, ebp, ebx, 0 |
398 | 398 | ||
399 | cmp eax, [esi+4] |
399 | cmp eax, [esi+4] |
400 | jne .skip |
400 | jne .skip |
401 | 401 | ||
402 | mov eax, [esi+8] |
402 | mov eax, [esi+8] |
403 | stdcall pci_write8, ebp, ebx, 0x3C, eax |
403 | stdcall pci_write8, ebp, ebx, 0x3C, eax |
404 | .skip: |
404 | .skip: |
405 | add esi, 16 |
405 | add esi, 16 |
406 | jmp .iterate |
406 | jmp .iterate |
407 | 407 | ||
408 | .done: |
408 | .done: |
409 | .fail: |
409 | .fail: |
410 | pop ebp |
410 | pop ebp |
411 | ret><><<> |
411 | ret><><<> |