Subversion Repositories Kolibri OS

Rev

Rev 9958 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 9958 Rev 9977
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2022. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2022. 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
$Revision: 9958 $
8
$Revision: 9977 $
9
 
9
 
10
MAX_IOAPICS = 2
10
MAX_IOAPICS = 2
11
 
11
 
12
uglobal
12
uglobal
13
IRQ_COUNT    rd  MAX_IOAPICS
13
IRQ_COUNT    rd  MAX_IOAPICS
14
irq_mode     rd  1              ; PIC/(IO)APIC
14
irq_mode     rd  1              ; PIC/(IO)APIC
15
IOAPIC_base  rd  MAX_IOAPICS
15
IOAPIC_base  rd  MAX_IOAPICS
16
ioapic_gsi_base rd MAX_IOAPICS  ; zero-based, i.e. not vector
16
ioapic_gsi_base rd MAX_IOAPICS  ; zero-based, i.e. not vector
17
ioapic_cnt   dd  ?              ; from MADT aka APIC table
17
ioapic_cnt   dd  ?              ; from MADT aka APIC table
18
ioapic_cur   dd  ?
18
ioapic_cur   dd  ?
19
LAPIC_BASE   rd  1
19
LAPIC_BASE   rd  1
20
endg
20
endg
21
 
21
 
22
APIC_ID         = 0x20
22
APIC_ID         = 0x20
23
APIC_TPR        = 0x80
23
APIC_TPR        = 0x80
24
APIC_EOI        = 0xb0
24
APIC_EOI        = 0xb0
25
APIC_LDR        = 0xd0
25
APIC_LDR        = 0xd0
26
APIC_DFR        = 0xe0
26
APIC_DFR        = 0xe0
27
APIC_SVR        = 0xf0
27
APIC_SVR        = 0xf0
28
APIC_ISR        = 0x100
28
APIC_ISR        = 0x100
29
APIC_ESR        = 0x280
29
APIC_ESR        = 0x280
30
APIC_ICRL       = 0x300
30
APIC_ICRL       = 0x300
31
APIC_ICRH       = 0x310
31
APIC_ICRH       = 0x310
32
APIC_LVT_LINT0  = 0x350
32
APIC_LVT_LINT0  = 0x350
33
APIC_LVT_LINT1  = 0x360
33
APIC_LVT_LINT1  = 0x360
34
APIC_LVT_err    = 0x370
34
APIC_LVT_err    = 0x370
35
 
35
 
36
; APIC timer
36
; APIC timer
37
APIC_LVT_timer  = 0x320
37
APIC_LVT_timer  = 0x320
38
APIC_timer_div  = 0x3e0
38
APIC_timer_div  = 0x3e0
39
APIC_timer_init = 0x380
39
APIC_timer_init = 0x380
40
APIC_timer_cur  = 0x390
40
APIC_timer_cur  = 0x390
41
; IOAPIC
41
; IOAPIC
42
IOAPIC_ID       = 0x0
42
IOAPIC_ID       = 0x0
43
IOAPIC_VER      = 0x1
43
IOAPIC_VER      = 0x1
44
IOAPIC_ARB      = 0x2
44
IOAPIC_ARB      = 0x2
45
IOAPIC_REDTBL   = 0x10
45
IOAPIC_REDTBL   = 0x10
46
 
46
 
47
align 4
47
align 4
48
APIC_init:
48
APIC_init:
49
        push    ebx
49
        push    ebx
50
        mov     [irq_mode], IRQ_PIC
50
        mov     [irq_mode], IRQ_PIC
51
 
51
 
52
        cmp     [acpi_ioapic_base], 0
52
        cmp     [acpi_ioapic_base], 0
53
        jz      .no_apic
53
        jz      .no_apic
54
 
54
 
55
        cmp     [acpi_lapic_base], 0
55
        cmp     [acpi_lapic_base], 0
56
        jz      .no_apic
56
        jz      .no_apic
57
 
57
 
58
; non-UEFI loaders don't load DEVICES.DAT but they zero out [acpi_dev_size]
58
; non-UEFI loaders don't load DEVICES.DAT but they zero out [acpi_dev_size]
59
        cmp     [acpi_dev_size], 0
59
        cmp     [acpi_dev_size], 0
60
        jz      @f
60
        jz      @f
61
        stdcall map_io_mem, [acpi_dev_data], [acpi_dev_size], PG_SWR
61
        stdcall map_io_mem, [acpi_dev_data], [acpi_dev_size], PG_SWR
62
        mov     [acpi_dev_data], eax
62
        mov     [acpi_dev_data], eax
63
        jmp     .loaded
63
        jmp     .loaded
64
@@:
64
@@:
65
 
65
 
66
        stdcall load_file, dev_data_path
66
        stdcall load_file, dev_data_path
67
        test    eax, eax
67
        test    eax, eax
68
        jz      .no_apic
68
        jz      .no_apic
69
 
69
 
70
        mov     [acpi_dev_data], eax
70
        mov     [acpi_dev_data], eax
71
        mov     [acpi_dev_size], ebx
71
        mov     [acpi_dev_size], ebx
72
.loaded:
72
.loaded:
73
 
73
 
74
; IOAPIC init
74
; IOAPIC init
75
        xor     ebx, ebx
75
        xor     ebx, ebx
76
@@:
76
@@:
77
        stdcall map_io_mem, [acpi_ioapic_base + ebx*4], 0x20, PG_GLOBAL + PG_NOCACHE + PG_SWR
77
        stdcall map_io_mem, [acpi_ioapic_base + ebx*4], 0x20, PG_GLOBAL + PG_NOCACHE + PG_SWR
78
        mov     [IOAPIC_base + ebx*4], eax
78
        mov     [IOAPIC_base + ebx*4], eax
79
        inc     ebx
79
        inc     ebx
80
        cmp     ebx, [ioapic_cnt]
80
        cmp     ebx, [ioapic_cnt]
81
        jnz     @b
81
        jnz     @b
82
 
82
 
83
        call    IRQ_mask_all
83
        call    IRQ_mask_all
84
        mov     [ioapic_cur], 0
84
        mov     [ioapic_cur], 0
85
.next_ioapic:
85
.next_ioapic:
86
        mov     edx, [ioapic_cur]
86
        mov     edx, [ioapic_cur]
87
        mov     eax, IOAPIC_VER
87
        mov     eax, IOAPIC_VER
88
        call    IOAPIC_read
88
        call    IOAPIC_read
89
        shr     eax, 16
89
        shr     eax, 16
90
        inc     al
90
        inc     al
91
        movzx   eax, al
91
        movzx   eax, al
92
        mov     ecx, [ioapic_gsi_base + edx*4]
92
        mov     ecx, [ioapic_gsi_base + edx*4]
93
        cmp     ecx, IRQ_RESERVED
93
        cmp     ecx, IRQ_RESERVED
94
        jae     .lapic_init
94
        jae     .lapic_init
95
        add     ecx, eax
95
        add     ecx, eax
96
        sub     ecx, IRQ_RESERVED
96
        sub     ecx, IRQ_RESERVED
97
        jbe     @f
97
        jbe     @f
98
        sub     eax, ecx
98
        sub     eax, ecx
99
@@:
99
@@:
100
        mov     [IRQ_COUNT + edx*4], eax
100
        mov     [IRQ_COUNT + edx*4], eax
101
 
101
 
102
        ; Reroute IOAPIC & mask all interrupts
102
        ; Reroute IOAPIC & mask all interrupts
103
        xor     ecx, ecx
103
        xor     ecx, ecx
104
        mov     eax, IOAPIC_REDTBL
104
        mov     eax, IOAPIC_REDTBL
105
.next_irq:
105
.next_irq:
106
        mov     ebx, eax
106
        mov     ebx, eax
107
        call    IOAPIC_read
107
        call    IOAPIC_read
108
        mov     ah, 0x08; Delivery Mode: Fixed, Destination Mode: Logical
108
        mov     ah, 0x08; Delivery Mode: Fixed, Destination Mode: Logical
109
        mov     al, cl
109
        mov     al, cl
110
        add     al, 0x20; vector
110
        add     al, 0x20; vector
111
        add     eax, [ioapic_gsi_base + edx*4]
111
        add     eax, [ioapic_gsi_base + edx*4]
112
        or      eax, 0x1a000; Mask Interrupt, level-triggered active-low
112
        or      eax, 0x1a000; Mask Interrupt, level-triggered active-low
113
        cmp     [ioapic_cur], 0
113
        cmp     [ioapic_cur], 0
114
        jnz     @f
114
        jnz     @f
115
        cmp     ecx, 16
115
        cmp     ecx, 16
116
        jae     @f
116
        jae     @f
117
        and     eax, NOT 0xa000 ; edge-triggered active-high for IRQ0-15
117
        and     eax, NOT 0xa000 ; edge-triggered active-high for IRQ0-15
118
@@:
118
@@:
119
        xchg    eax, ebx
119
        xchg    eax, ebx
120
        call    IOAPIC_write
120
        call    IOAPIC_write
121
        inc     eax
121
        inc     eax
122
        mov     ebx, eax
122
        mov     ebx, eax
123
        call    IOAPIC_read
123
        call    IOAPIC_read
124
        or      eax, 0xff000000; Destination Field
124
        or      eax, 0xff000000; Destination Field
125
        xchg    eax, ebx
125
        xchg    eax, ebx
126
        call    IOAPIC_write
126
        call    IOAPIC_write
127
        inc     eax
127
        inc     eax
128
        inc     ecx
128
        inc     ecx
129
        cmp     ecx, [IRQ_COUNT + edx*4]
129
        cmp     ecx, [IRQ_COUNT + edx*4]
130
        jb      .next_irq
130
        jb      .next_irq
131
 
131
 
132
        inc     [ioapic_cur]
132
        inc     [ioapic_cur]
133
        inc     edx
133
        inc     edx
134
        cmp     edx, [ioapic_cnt]
134
        cmp     edx, [ioapic_cnt]
135
        jnz     .next_ioapic
135
        jnz     .next_ioapic
136
 
136
 
137
.lapic_init:
137
.lapic_init:
138
        call    LAPIC_init
138
        call    LAPIC_init
139
 
139
 
140
        mov     [irq_mode], IRQ_APIC
140
        mov     [irq_mode], IRQ_APIC
141
 
141
 
142
        mov     al, 0x70
142
        mov     al, 0x70
143
        out     0x22, al
143
        out     0x22, al
144
        mov     al, 1
144
        mov     al, 1
145
        out     0x23, al
145
        out     0x23, al
146
 
146
 
147
        call    pci_irq_fixup
147
        call    pci_irq_fixup
148
.no_apic:
148
.no_apic:
149
        pop     ebx
149
        pop     ebx
150
        ret
150
        ret
151
 
151
 
152
;===========================================================
152
;===========================================================
153
align 4
153
align 4
154
LAPIC_init:
154
LAPIC_init:
155
 
155
 
156
        mov     eax, [LAPIC_BASE]
156
        mov     eax, [LAPIC_BASE]
157
        test    eax, eax
157
        test    eax, eax
158
        jnz     @f
158
        jnz     @f
159
        stdcall map_io_mem, [acpi_lapic_base], 0x1000, PG_GLOBAL + PG_NOCACHE + PG_SWR
159
        stdcall map_io_mem, [acpi_lapic_base], 0x1000, PG_GLOBAL + PG_NOCACHE + PG_SWR
160
        mov     [LAPIC_BASE], eax
160
        mov     [LAPIC_BASE], eax
161
@@:
161
@@:
162
        mov     esi, eax
162
        mov     esi, eax
163
 
163
 
164
        ; Program Destination Format Register for Flat mode.
164
        ; Program Destination Format Register for Flat mode.
165
        mov     eax, [esi + APIC_DFR]
165
        mov     eax, [esi + APIC_DFR]
166
        or      eax, 0xf0000000
166
        or      eax, 0xf0000000
167
        mov     [esi + APIC_DFR], eax
167
        mov     [esi + APIC_DFR], eax
168
 
168
 
169
        ; Program Logical Destination Register.
169
        ; Program Logical Destination Register.
170
        mov     eax, [esi + APIC_LDR]
170
        mov     eax, [esi + APIC_LDR]
171
        ;and  eax, 0xff000000
171
        ;and  eax, 0xff000000
172
        and     eax, 0x00ffffff
172
        and     eax, 0x00ffffff
173
        or      eax, 0x01000000;!!!!!!!!!!!!
173
        or      eax, 0x01000000;!!!!!!!!!!!!
174
        mov     [esi + APIC_LDR], eax
174
        mov     [esi + APIC_LDR], eax
175
 
175
 
176
        ; Task Priority Register initialization.
176
        ; Task Priority Register initialization.
177
        mov     eax, [esi + APIC_TPR]
177
        mov     eax, [esi + APIC_TPR]
178
        and     eax, 0xffffff00
178
        and     eax, 0xffffff00
179
        mov     [esi + APIC_TPR], eax
179
        mov     [esi + APIC_TPR], eax
180
 
180
 
181
        ; Flush the queue
181
        ; Flush the queue
182
        mov     edx, 0
182
        xor     edx, edx
183
.nxt2:
183
.nxt2:
184
        mov     ecx, 32
184
        mov     ecx, 32
185
        mov     eax, [esi + APIC_ISR + edx]
185
        mov     eax, [esi + APIC_ISR + edx]
186
.nxt:
186
.nxt:
187
        shr     eax, 1
187
        shr     eax, 1
188
        jnc     @f
188
        jnc     @f
189
        mov     dword [esi + APIC_EOI], 0; EOI
189
        mov     dword [esi + APIC_EOI], 0; EOI
190
@@:
190
@@:
191
        loop    .nxt
191
        loop    .nxt
192
 
192
 
193
        add     edx, 0x10
193
        add     edx, 0x10
194
        cmp     edx, 0x170
194
        cmp     edx, 0x170
195
        jbe     .nxt2
195
        jbe     .nxt2
196
 
196
 
197
        ; Spurious-Interrupt Vector Register initialization.
197
        ; Spurious-Interrupt Vector Register initialization.
198
        mov     eax, [esi + APIC_SVR]
198
        mov     eax, [esi + APIC_SVR]
199
        or      eax, 0x1ff
199
        or      eax, 0x1ff
200
        and     eax, 0xfffffdff
200
        and     eax, 0xfffffdff
201
        mov     [esi + APIC_SVR], eax
201
        mov     [esi + APIC_SVR], eax
202
 
202
 
203
        ; Initialize LVT LINT0 register. (INTR)
203
        ; Initialize LVT LINT0 register. (INTR)
204
        mov     eax, 0x00700
204
        mov     eax, 0x00700
205
        ; mov eax, 0x10700
205
        ; mov eax, 0x10700
206
        mov     [esi + APIC_LVT_LINT0], eax
206
        mov     [esi + APIC_LVT_LINT0], eax
207
 
207
 
208
        ; Initialize LVT LINT1 register. (NMI)
208
        ; Initialize LVT LINT1 register. (NMI)
209
        mov     eax, 0x00400
209
        mov     eax, 0x00400
210
        mov     [esi + APIC_LVT_LINT1], eax
210
        mov     [esi + APIC_LVT_LINT1], eax
211
 
211
 
212
        ; Initialize LVT Error register.
212
        ; Initialize LVT Error register.
213
        mov     eax, [esi + APIC_LVT_err]
213
        mov     eax, [esi + APIC_LVT_err]
214
        or      eax, 0x10000; bit 16
214
        or      eax, 0x10000; bit 16
215
        mov     [esi + APIC_LVT_err], eax
215
        mov     [esi + APIC_LVT_err], eax
216
 
216
 
217
        ; LAPIC timer
217
        ; LAPIC timer
218
        ; pre init
218
        ; pre init
219
        mov     dword[esi + APIC_timer_div], 1011b; 1
219
        mov     dword[esi + APIC_timer_div], 1011b; 1
220
        mov     dword[esi + APIC_timer_init], 0xffffffff; max val
220
        mov     dword[esi + APIC_timer_init], 0xffffffff; max val
221
        push    esi
221
        push    esi
222
        mov     esi, 640    ; wait 0.64 sec
222
        mov     esi, 640    ; wait 0.64 sec
223
        call    delay_ms
223
        call    delay_ms
224
        pop     esi
224
        pop     esi
225
        mov     eax, [esi + APIC_timer_cur]; read current tick couner
225
        mov     eax, [esi + APIC_timer_cur]; read current tick couner
226
        xor     eax, 0xffffffff   ; eax = 0xffffffff - eax
226
        xor     eax, 0xffffffff   ; eax = 0xffffffff - eax
227
        shr     eax, 6      ; eax /= 64; APIC ticks per 0.01 sec
227
        shr     eax, 6      ; eax /= 64; APIC ticks per 0.01 sec
228
 
228
 
229
        ; Start (every 0.01 sec)
229
        ; Start (every 0.01 sec)
230
        mov     dword[esi + APIC_LVT_timer], 0x30020; periodic int 0x20
230
        mov     dword[esi + APIC_LVT_timer], 0x30020; periodic int 0x20
231
        mov     dword[esi + APIC_timer_init], eax
231
        mov     dword[esi + APIC_timer_init], eax
232
 
232
 
233
.done:
233
.done:
234
        ret
234
        ret
235
 
235
 
236
;===========================================================
236
;===========================================================
237
; IOAPIC implementation
237
; IOAPIC implementation
238
align 4
238
align 4
239
IOAPIC_read:
239
IOAPIC_read:
240
; in : EAX - IOAPIC register
240
; in : EAX - IOAPIC register
241
; out: EAX - readed value
241
; out: EAX - readed value
242
        push    esi
242
        push    esi
243
        mov     esi, [ioapic_cur]
243
        mov     esi, [ioapic_cur]
244
        mov     esi, [IOAPIC_base + esi*4]
244
        mov     esi, [IOAPIC_base + esi*4]
245
        mov     [esi], eax
245
        mov     [esi], eax
246
        mov     eax, [esi + 0x10]
246
        mov     eax, [esi + 0x10]
247
        pop     esi
247
        pop     esi
248
        ret
248
        ret
249
 
249
 
250
align 4
250
align 4
251
IOAPIC_write:
251
IOAPIC_write:
252
; in :  EAX - IOAPIC register
252
; in :  EAX - IOAPIC register
253
;       EBX - value
253
;       EBX - value
254
; out:  none
254
; out:  none
255
        push    esi
255
        push    esi
256
        mov     esi, [ioapic_cur]
256
        mov     esi, [ioapic_cur]
257
        mov     esi, [IOAPIC_base + esi*4]
257
        mov     esi, [IOAPIC_base + esi*4]
258
        mov     [esi], eax
258
        mov     [esi], eax
259
        mov     [esi + 0x10], ebx
259
        mov     [esi + 0x10], ebx
260
        pop     esi
260
        pop     esi
261
        ret
261
        ret
262
;===========================================================
262
;===========================================================
263
; Remap all IRQ to 0x20+ Vectors
263
; Remap all IRQ to 0x20+ Vectors
264
; IRQ0 to vector 0x20, IRQ1 to vector 0x21....
264
; IRQ0 to vector 0x20, IRQ1 to vector 0x21....
265
align 4
265
align 4
266
PIC_init:
266
PIC_init:
267
        mov     [IRQ_COUNT], 16
267
        mov     [IRQ_COUNT], 16
268
        cli
268
        cli
269
        mov     al, 0x11        ;  icw4, edge triggered
269
        mov     al, 0x11        ;  icw4, edge triggered
270
        out     0x20, al
270
        out     0x20, al
271
        out     0xA0, al
271
        out     0xA0, al
272
 
272
 
273
        mov     al, 0x20        ;  generate 0x20 +
273
        mov     al, 0x20        ;  generate 0x20 +
274
        out     0x21, al
274
        out     0x21, al
275
        mov     al, 0x28        ;  generate 0x28 +
275
        mov     al, 0x28        ;  generate 0x28 +
276
        out     0xA1, al
276
        out     0xA1, al
277
 
277
 
278
        mov     al, 0x04        ;  slave at irq2
278
        mov     al, 0x04        ;  slave at irq2
279
        out     0x21, al
279
        out     0x21, al
280
        mov     al, 0x02        ;  at irq9
280
        mov     al, 0x02        ;  at irq9
281
        out     0xA1, al
281
        out     0xA1, al
282
 
282
 
283
        mov     al, 0x01        ;  8086 mode
283
        mov     al, 0x01        ;  8086 mode
284
        out     0x21, al
284
        out     0x21, al
285
        out     0xA1, al
285
        out     0xA1, al
286
 
286
 
287
        call    IRQ_mask_all
287
        call    IRQ_mask_all
288
        ret
288
        ret
289
 
289
 
290
; -----------------------------------------
290
; -----------------------------------------
291
; TIMER SET TO 1/100 S
291
; TIMER SET TO 1/100 S
292
align 4
292
align 4
293
PIT_init:
293
PIT_init:
294
        mov     al, 0x34   ; set to 100Hz
294
        mov     al, 0x34   ; set to 100Hz
295
        out     0x43, al
295
        out     0x43, al
296
        mov     al, 0x9b   ; lsb    1193180 / 1193
296
        mov     al, 0x9b   ; lsb    1193180 / 1193
297
        out     0x40, al
297
        out     0x40, al
298
        mov     al, 0x2e   ; msb
298
        mov     al, 0x2e   ; msb
299
        out     0x40, al
299
        out     0x40, al
300
        ret
300
        ret
301
 
301
 
302
; -----------------------------------------
302
; -----------------------------------------
303
align 4
303
align 4
304
unmask_timer:
304
unmask_timer:
305
        cmp     [irq_mode], IRQ_APIC
305
        cmp     [irq_mode], IRQ_APIC
306
        je      @f
306
        je      @f
307
 
307
 
308
        stdcall enable_irq, 0
308
        stdcall enable_irq, 0
309
        ret
309
        ret
310
@@:
310
@@:
311
        ; use PIT
311
        ; use PIT
312
        ; in some systems PIT no connected to IOAPIC
312
        ; in some systems PIT no connected to IOAPIC
313
        ; mov   eax, 0x14
313
        ; mov   eax, 0x14
314
        ; call  IOAPIC_read
314
        ; call  IOAPIC_read
315
        ; mov   ah, 0x09                ; Delivery Mode: Lowest Priority, Destination Mode: Logical
315
        ; mov   ah, 0x09                ; Delivery Mode: Lowest Priority, Destination Mode: Logical
316
        ; mov   al, 0x20
316
        ; mov   al, 0x20
317
        ; or    eax, 0x10000            ; Mask Interrupt
317
        ; or    eax, 0x10000            ; Mask Interrupt
318
        ; mov   ebx, eax
318
        ; mov   ebx, eax
319
        ; mov   eax, 0x14
319
        ; mov   eax, 0x14
320
        ; call  IOAPIC_write
320
        ; call  IOAPIC_write
321
        ; stdcall enable_irq, 2
321
        ; stdcall enable_irq, 2
322
        ; ret
322
        ; ret
323
 
323
 
324
        ; use LAPIC timer
324
        ; use LAPIC timer
325
        mov     esi, [LAPIC_BASE]
325
        mov     esi, [LAPIC_BASE]
326
        mov     eax, [esi + APIC_LVT_timer]
326
        mov     eax, [esi + APIC_LVT_timer]
327
        and     eax, 0xfffeffff
327
        and     eax, 0xfffeffff
328
        mov     [esi + APIC_LVT_timer], eax
328
        mov     [esi + APIC_LVT_timer], eax
329
        ret
329
        ret
330
 
330
 
331
; -----------------------------------------
331
; -----------------------------------------
332
; Disable all IRQ
332
; Disable all IRQ
333
align 4
333
align 4
334
IRQ_mask_all:
334
IRQ_mask_all:
335
        cmp     [irq_mode], IRQ_APIC
335
        cmp     [irq_mode], IRQ_APIC
336
        je      .APIC
336
        je      .APIC
337
 
337
 
338
        mov     al, 0xFF
338
        mov     al, 0xFF
339
        out     0x21, al
339
        out     0x21, al
340
        out     0xA1, al
340
        out     0xA1, al
341
        mov     ecx, 0x1000
341
        mov     ecx, 0x1000
342
        ret
342
        ret
343
.APIC:
343
.APIC:
344
        cmp     [IOAPIC_base], 0
344
        cmp     [IOAPIC_base], 0
345
        jz      .done
345
        jz      .done
346
        mov     [ioapic_cur], 0
346
        mov     [ioapic_cur], 0
347
.next_ioapic:
347
.next_ioapic:
348
        mov     edx, [ioapic_cur]
348
        mov     edx, [ioapic_cur]
349
        mov     ecx, [IRQ_COUNT + edx*4]
349
        mov     ecx, [IRQ_COUNT + edx*4]
350
        mov     eax, 0x10
350
        mov     eax, 0x10
351
@@:
351
@@:
352
        mov     ebx, eax
352
        mov     ebx, eax
353
        call    IOAPIC_read
353
        call    IOAPIC_read
354
        or      eax, 0x10000; bit 16
354
        or      eax, 0x10000; bit 16
355
        xchg    eax, ebx
355
        xchg    eax, ebx
356
        call    IOAPIC_write
356
        call    IOAPIC_write
357
        inc     eax
357
        inc     eax
358
        inc     eax
358
        inc     eax
359
        loop    @b
359
        loop    @b
360
 
360
 
361
        inc     [ioapic_cur]
361
        inc     [ioapic_cur]
362
        inc     edx
362
        inc     edx
363
        cmp     edx, [ioapic_cnt]
363
        cmp     edx, [ioapic_cnt]
364
        jnz     .next_ioapic
364
        jnz     .next_ioapic
365
.done:
365
.done:
366
        ret
366
        ret
367
 
367
 
368
; -----------------------------------------
368
; -----------------------------------------
369
; End Of Interrupt
369
; End Of Interrupt
370
; cl - IRQ number
370
; cl - IRQ number
371
align 4
371
align 4
372
irq_eoi:         ; __fastcall
372
irq_eoi:         ; __fastcall
373
        cmp     [irq_mode], IRQ_APIC
373
        cmp     [irq_mode], IRQ_APIC
374
        je      .APIC
374
        je      .APIC
375
 
375
 
376
        cmp     cl, 8
376
        cmp     cl, 8
377
        mov     al, 0x20
377
        mov     al, 0x20
378
        jb      @f
378
        jb      @f
379
        out     0xa0, al
379
        out     0xa0, al
380
@@:
380
@@:
381
        out     0x20, al
381
        out     0x20, al
382
        ret
382
        ret
383
 
383
 
384
.APIC:
384
.APIC:
385
        mov     eax, [LAPIC_BASE]
385
        mov     eax, [LAPIC_BASE]
386
        mov     dword [eax + APIC_EOI], 0; EOI
386
        mov     dword [eax + APIC_EOI], 0; EOI
387
        ret
387
        ret
388
 
388
 
389
; -----------------------------------------
389
; -----------------------------------------
390
; from dll.inc
390
; from dll.inc
391
align 4
391
align 4
392
proc enable_irq stdcall, irq_line:dword
392
proc enable_irq stdcall, irq_line:dword
393
        mov     ebx, [irq_line]
393
        mov     ebx, [irq_line]
394
        cmp     [irq_mode], IRQ_APIC
394
        cmp     [irq_mode], IRQ_APIC
395
        je      .APIC
395
        je      .APIC
396
 
396
 
397
        mov     edx, 0x21
397
        mov     edx, 0x21
398
        cmp     ebx, 8
398
        cmp     ebx, 8
399
        jb      @F
399
        jb      @F
400
 
400
 
401
        mov     edx, 0xA1
401
        mov     edx, 0xA1
402
        sub     ebx, 8
402
        sub     ebx, 8
403
@@:
403
@@:
404
        in      al, dx
404
        in      al, dx
405
        btr     eax, ebx
405
        btr     eax, ebx
406
        out     dx, al
406
        out     dx, al
407
        ret
407
        ret
408
.APIC:
408
.APIC:
409
        push    [ioapic_cur]
409
        push    [ioapic_cur]
410
        xor     eax, eax
410
        xor     eax, eax
411
.next_ioapic:
411
.next_ioapic:
412
        mov     ecx, [ioapic_gsi_base+eax*4]
412
        mov     ecx, [ioapic_gsi_base+eax*4]
413
        add     ecx, [IRQ_COUNT+eax*4]
413
        add     ecx, [IRQ_COUNT+eax*4]
414
        cmp     ebx, ecx
414
        cmp     ebx, ecx
415
        jb      .found
415
        jb      .found
416
        inc     eax
416
        inc     eax
417
        cmp     eax, [ioapic_cnt]
417
        cmp     eax, [ioapic_cnt]
418
        jnz     .next_ioapic
418
        jnz     .next_ioapic
419
        jmp     .done
419
        jmp     .done
420
.found:
420
.found:
421
        mov     [ioapic_cur], eax
421
        mov     [ioapic_cur], eax
422
        sub     ebx, [ioapic_gsi_base+eax*4]
422
        sub     ebx, [ioapic_gsi_base+eax*4]
423
        shl     ebx, 1
423
        shl     ebx, 1
424
        add     ebx, 0x10
424
        add     ebx, 0x10
425
        mov     eax, ebx
425
        mov     eax, ebx
426
        call    IOAPIC_read
426
        call    IOAPIC_read
427
        and     eax, 0xfffeffff; bit 16
427
        and     eax, 0xfffeffff; bit 16
428
        xchg    eax, ebx
428
        xchg    eax, ebx
429
        call    IOAPIC_write
429
        call    IOAPIC_write
430
.done:
430
.done:
431
        pop     [ioapic_cur]
431
        pop     [ioapic_cur]
432
        ret
432
        ret
433
endp
433
endp
434
 
434
 
435
proc disable_irq stdcall, irq_line:dword
435
proc disable_irq stdcall, irq_line:dword
436
        mov     ebx, [irq_line]
436
        mov     ebx, [irq_line]
437
        cmp     [irq_mode], IRQ_APIC
437
        cmp     [irq_mode], IRQ_APIC
438
        je      .APIC
438
        je      .APIC
439
 
439
 
440
        mov     edx, 0x21
440
        mov     edx, 0x21
441
        cmp     ebx, 8
441
        cmp     ebx, 8
442
        jb      @F
442
        jb      @F
443
 
443
 
444
        mov     edx, 0xA1
444
        mov     edx, 0xA1
445
        sub     ebx, 8
445
        sub     ebx, 8
446
@@:
446
@@:
447
        in      al, dx
447
        in      al, dx
448
        bts     eax, ebx
448
        bts     eax, ebx
449
        out     dx, al
449
        out     dx, al
450
        ret
450
        ret
451
.APIC:
451
.APIC:
452
        push    [ioapic_cur]
452
        push    [ioapic_cur]
453
        xor     eax, eax
453
        xor     eax, eax
454
.next_ioapic:
454
.next_ioapic:
455
        mov     ecx, [ioapic_gsi_base + eax*4]
455
        mov     ecx, [ioapic_gsi_base + eax*4]
456
        add     ecx, [IRQ_COUNT + eax*4]
456
        add     ecx, [IRQ_COUNT + eax*4]
457
        cmp     ebx, ecx
457
        cmp     ebx, ecx
458
        jae     .found
458
        jae     .found
459
        inc     eax
459
        inc     eax
460
        cmp     eax, [ioapic_cnt]
460
        cmp     eax, [ioapic_cnt]
461
        jnz     .next_ioapic
461
        jnz     .next_ioapic
462
        jmp     .done
462
        jmp     .done
463
.found:
463
.found:
464
        mov     [ioapic_cur], eax
464
        mov     [ioapic_cur], eax
465
        sub     ebx, [ioapic_gsi_base+eax*4]
465
        sub     ebx, [ioapic_gsi_base+eax*4]
466
        shl     ebx, 1
466
        shl     ebx, 1
467
        add     ebx, 0x10
467
        add     ebx, 0x10
468
        mov     eax, ebx
468
        mov     eax, ebx
469
        call    IOAPIC_read
469
        call    IOAPIC_read
470
        or      eax, 0x10000; bit 16
470
        or      eax, 0x10000; bit 16
471
        xchg    eax, ebx
471
        xchg    eax, ebx
472
        call    IOAPIC_write
472
        call    IOAPIC_write
473
.done:
473
.done:
474
        pop     [ioapic_cur]
474
        pop     [ioapic_cur]
475
        ret
475
        ret
476
endp
476
endp
477
 
477
 
478
align 4
478
align 4
479
pci_irq_fixup:
479
pci_irq_fixup:
480
 
480
 
481
        push    ebp
481
        push    ebp
482
 
482
 
483
        mov     esi, [acpi_dev_data]
483
        mov     esi, [acpi_dev_data]
484
        mov     ebx, [acpi_dev_size]
484
        mov     ebx, [acpi_dev_size]
485
 
485
 
486
        lea     edi, [esi + ebx]
486
        lea     edi, [esi + ebx]
487
 
487
 
488
.iterate:
488
.iterate:
489
 
489
 
490
        cmp     esi, edi
490
        cmp     esi, edi
491
        jae     .done
491
        jae     .done
492
 
492
 
493
        mov     eax, [esi]
493
        mov     eax, [esi]
494
 
494
 
495
        cmp     eax, -1
495
        cmp     eax, -1
496
        je      .done
496
        je      .done
497
 
497
 
498
        movzx   ebx, al
498
        movzx   ebx, al
499
        movzx   ebp, ah
499
        movzx   ebp, ah
500
 
500
 
501
        stdcall pci_read32, ebp, ebx, 0
501
        stdcall pci_read32, ebp, ebx, 0
502
 
502
 
503
        cmp     eax, [esi+4]
503
        cmp     eax, [esi+4]
504
        jne     .skip
504
        jne     .skip
505
 
505
 
506
        mov     eax, [esi+8]
506
        mov     eax, [esi+8]
507
        stdcall pci_write8, ebp, ebx, 0x3C, eax
507
        stdcall pci_write8, ebp, ebx, 0x3C, eax
508
.skip:
508
.skip:
509
        add     esi, 16
509
        add     esi, 16
510
        jmp     .iterate
510
        jmp     .iterate
511
 
511
 
512
.done:
512
.done:
513
.fail:
513
.fail:
514
        pop     ebp
514
        pop     ebp
515
        ret
515
        ret
516
 
516
 
517
align 4
517
align 4
518
get_clock_ns:
518
get_clock_ns:
519
 
519
 
520
        mov     eax, [hpet_base]
520
        mov     eax, [hpet_base]
521
        test    eax, eax
521
        test    eax, eax
522
        jz      .old_tics
522
        jz      .old_tics
523
 
523
 
524
        push    ebx
524
        push    ebx
525
        push    esi
525
        push    esi
526
        pushfd
526
        pushfd
527
        cli
527
        cli
528
 
528
 
529
        mov     ebx, eax
529
        mov     ebx, eax
530
@@:
530
@@:
531
        mov     edx, [ebx+0xF4]
531
        mov     edx, [ebx+0xF4]
532
        mov     eax, [ebx+0xF0]
532
        mov     eax, [ebx+0xF0]
533
        mov     ecx, [ebx+0xF4]
533
        mov     ecx, [ebx+0xF4]
534
        cmp     ecx, edx
534
        cmp     ecx, edx
535
        jne     @B
535
        jne     @B
536
        popfd
536
        popfd
537
 
537
 
538
;96-bit arithmetic
538
;96-bit arithmetic
539
;ebx - low dword
539
;ebx - low dword
540
;esi - medium dword
540
;esi - medium dword
541
;edx - high dword
541
;edx - high dword
542
 
542
 
543
        mul     [hpet_period]
543
        mul     [hpet_period]
544
        mov     ebx, eax
544
        mov     ebx, eax
545
        mov     esi, edx
545
        mov     esi, edx
546
 
546
 
547
        mov     eax, ecx
547
        mov     eax, ecx
548
        mul     [hpet_period]
548
        mul     [hpet_period]
549
        add     esi, eax
549
        add     esi, eax
550
        adc     edx, 0
550
        adc     edx, 0
551
        mov     eax, ebx
551
        mov     eax, ebx
552
        mov     ebx, esi
552
        mov     ebx, esi
553
        shrd    eax, ebx, 10
553
        shrd    eax, ebx, 10
554
        shrd    esi, edx, 10
554
        shrd    esi, edx, 10
555
        mov     edx, esi
555
        mov     edx, esi
556
 
556
 
557
        pop     esi
557
        pop     esi
558
        pop     ebx
558
        pop     ebx
559
        ret
559
        ret
560
 
560
 
561
.old_tics:
561
.old_tics:
562
        mov     eax, [timer_ticks]
562
        mov     eax, [timer_ticks]
563
        mov     edx, 10000000
563
        mov     edx, 10000000
564
        mul     edx
564
        mul     edx
565
        ret
565
        ret