Subversion Repositories Kolibri OS

Rev

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