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