Subversion Repositories Kolibri OS

Rev

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