Subversion Repositories Kolibri OS

Rev

Rev 2443 | Rev 3320 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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