Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
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
64
        stdcall map_io_mem, [acpi_ioapic_base], 0x20, PG_SW
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
        ; Check MSR support
125
        ;....
126
        ; Get LAPIC base address
127
; mov ecx, 0x1b
128
; rdmsr       ; it may be replaced to
129
; and ax, 0xf000    ; mov eax, 0xfee00000
130
 
131
        stdcall map_io_mem, [acpi_lapic_base], 0x1000, PG_SW
132
        mov     [LAPIC_BASE], eax
133
        mov     esi, eax
134
 
135
        ; Program Destination Format Register for Flat mode.
136
        mov     eax, [esi + APIC_DFR]
137
        or      eax, 0xf0000000
138
        mov     [esi + APIC_DFR], eax
139
 
140
        ; Program Logical Destination Register.
141
        mov     eax, [esi + APIC_LDR]
142
        ;and  eax, 0xff000000
143
        and     eax, 0x00ffffff
144
        or      eax, 0x01000000;!!!!!!!!!!!!
145
        mov     [esi + APIC_LDR], eax
146
 
147
        ; Task Priority Register initialization.
148
        mov     eax, [esi + APIC_TPR]
149
        and     eax, 0xffffff00
150
        mov     [esi + APIC_TPR], eax
151
 
152
        ; Flush the queue
153
        mov     edx, 0
154
.nxt2:
155
        mov     ecx, 32
156
        mov     eax, [esi + APIC_ISR + edx]
157
.nxt:
158
        shr     eax, 1
159
        jnc     @f
160
        mov     dword [esi + APIC_EOI], 0; EOI
161
@@:
162
        loop    .nxt
163
 
164
        add     edx, 0x10
165
        cmp     edx, 0x170
166
        jbe     .nxt2
167
 
168
        ; Spurious-Interrupt Vector Register initialization.
169
        mov     eax, [esi + APIC_SVR]
170
        or      eax, 0x1ff
171
        and     eax, 0xfffffdff
172
        mov     [esi + APIC_SVR], eax
173
 
174
        ; Initialize LVT LINT0 register. (INTR)
175
        mov     eax, 0x00700
176
        ; mov eax, 0x10700
177
        mov     [esi + APIC_LVT_LINT0], eax
178
 
179
        ; Initialize LVT LINT1 register. (NMI)
180
        mov     eax, 0x00400
181
        mov     [esi + APIC_LVT_LINT1], eax
182
 
183
        ; Initialize LVT Error register.
184
        mov     eax, [esi + APIC_LVT_err]
185
        or      eax, 0x10000; bit 16
186
        mov     [esi + APIC_LVT_err], eax
187
 
188
        ; LAPIC timer
189
        ; pre init
190
        mov     dword[esi + APIC_timer_div], 1011b; 1
191
        mov     dword[esi + APIC_timer_init], 0xffffffff; max val
192
        push    esi
193
        mov     esi, 640    ; wait 0.64 sec
194
        call    delay_ms
195
        pop     esi
196
        mov     eax, [esi + APIC_timer_cur]; read current tick couner
197
        xor     eax, 0xffffffff   ; eax = 0xffffffff - eax
198
        shr     eax, 6      ; eax /= 64; APIC ticks per 0.01 sec
199
 
200
        ; Start (every 0.01 sec)
201
        mov     dword[esi + APIC_LVT_timer], 0x30020; periodic int 0x20
202
        mov     dword[esi + APIC_timer_init], eax
203
        ret
204
 
205
;===========================================================
206
; IOAPIC implementation
207
align 4
208
IOAPIC_read:
209
; in : EAX - IOAPIC register
210
; out: EAX - readed value
211
        push    esi
212
        mov     esi, [IOAPIC_base]
213
        mov     [esi], eax
214
        mov     eax, [esi + 0x10]
215
        pop     esi
216
        ret
217
 
218
align 4
219
IOAPIC_write:
220
; in :  EAX - IOAPIC register
221
;       EBX - value
222
; out:  none
223
        push    esi
224
        mov     esi, [IOAPIC_base]
225
        mov     [esi], eax
226
        mov     [esi + 0x10], ebx
227
        pop     esi
228
        ret
229
;===========================================================
230
; Remap all IRQ to 0x20+ Vectors
231
; IRQ0 to vector 0x20, IRQ1 to vector 0x21....
232
align 4
233
PIC_init:
234
        cli
235
        mov     al, 0x11        ;  icw4, edge triggered
236
        out     0x20, al
237
        out     0xA0, al
238
 
239
        mov     al, 0x20        ;  generate 0x20 +
240
        out     0x21, al
241
        mov     al, 0x28        ;  generate 0x28 +
242
        out     0xA1, al
243
 
244
        mov     al, 0x04        ;  slave at irq2
245
        out     0x21, al
246
        mov     al, 0x02        ;  at irq9
247
        out     0xA1, al
248
 
249
        mov     al, 0x01        ;  8086 mode
250
        out     0x21, al
251
        out     0xA1, al
252
 
253
        call    IRQ_mask_all
254
        ; mov   dword[irq_type_to_set], IRQ_TYPE_PIC
255
        ret
256
 
257
; -----------------------------------------
258
; TIMER SET TO 1/100 S
259
align 4
260
PIT_init:
261
        mov     al, 0x34   ; set to 100Hz
262
        out     0x43, al
263
        mov     al, 0x9b   ; lsb    1193180 / 1193
264
        out     0x40, al
265
        mov     al, 0x2e   ; msb
266
        out     0x40, al
267
        ret
268
 
269
; -----------------------------------------
270
align 4
271
unmask_timer:
272
        cmp     [irq_mode], IRQ_APIC
273
        je      @f
274
 
275
        stdcall enable_irq, 0
276
        ret
277
@@:
278
        ; use PIT
279
        ; in some systems PIT no connected to IOAPIC
280
        ; mov   eax, 0x14
281
        ; call  IOAPIC_read
282
        ; mov   ah, 0x09                ; Delivery Mode: Lowest Priority, Destination Mode: Logical
283
        ; mov   al, 0x20
284
        ; or    eax, 0x10000            ; Mask Interrupt
285
        ; mov   ebx, eax
286
        ; mov   eax, 0x14
287
        ; call  IOAPIC_write
288
        ; stdcall enable_irq, 2
289
        ; ret
290
 
291
        ; use LAPIC timer
292
        mov     esi, [LAPIC_BASE]
293
        mov     eax, [esi + APIC_LVT_timer]
294
        and     eax, 0xfffeffff
295
        mov     [esi + APIC_LVT_timer], eax
296
        ret
297
 
298
; -----------------------------------------
299
; Disable all IRQ
300
align 4
301
IRQ_mask_all:
302
        cmp     [irq_mode], IRQ_APIC
303
        je      .APIC
304
 
305
        mov     al, 0xFF
306
        out     0x21, al
307
        out     0xA1, al
308
        mov     ecx, 0x1000
309
        ret
310
.APIC:
311
        mov     ecx, [IRQ_COUNT]
312
        mov     eax, 0x10
313
@@:
314
        mov     ebx, eax
315
        call    IOAPIC_read
316
        or      eax, 0x10000; bit 16
317
        xchg    eax, ebx
318
        call    IOAPIC_write
319
        inc     eax
320
        inc     eax
321
        loop    @b
322
        ret
323
 
324
; -----------------------------------------
325
; End Of Interrupt
326
; cl - IRQ number
327
align 4
328
irq_eoi:         ; __fastcall
329
        cmp     [irq_mode], IRQ_APIC
330
        je      .APIC
331
 
332
        cmp     cl, 8
333
        mov     al, 0x20
334
        jb      @f
335
        out     0xa0, al
336
@@:
337
        out     0x20, al
338
        ret
339
 
340
.APIC:
341
        mov     eax, [LAPIC_BASE]
342
        mov     dword [eax + APIC_EOI], 0; EOI
343
        ret
344
 
345
; -----------------------------------------
346
; from dll.inc
347
align 4
348
proc enable_irq stdcall, irq_line:dword
349
        mov     ebx, [irq_line]
350
        cmp     [irq_mode], IRQ_APIC
351
        je      .APIC
352
 
353
        mov     edx, 0x21
354
        cmp     ebx, 8
355
        jb      @F
356
 
357
        mov     edx, 0xA1
358
        sub     ebx, 8
359
@@:
360
        in      al, dx
361
        btr     eax, ebx
362
        out     dx, al
363
        ret
364
.APIC:
365
        shl     ebx, 1
366
        add     ebx, 0x10
367
        mov     eax, ebx
368
        call    IOAPIC_read
369
        and     eax, 0xfffeffff; bit 16
370
        xchg    eax, ebx
371
        call    IOAPIC_write
372
        ret
373
endp
374
 
375
align 4
376
pci_irq_fixup:
377
 
378
        push    ebp
379
 
380
        mov     esi, [acpi_dev_data]
381
        mov     ebx, [acpi_dev_size]
382
 
383
        lea     edi, [esi+ebx]
384
 
385
.iterate:
386
 
387
        cmp     esi, edi
388
        jae     .done
389
 
390
        mov     eax, [esi]
391
 
392
        cmp     eax, -1
393
        je      .done
394
 
395
        movzx   ebx, al
396
        movzx   ebp, ah
397
 
398
        stdcall pci_read32, ebp, ebx, 0
399
 
400
        cmp     eax, [esi+4]
401
        jne     .skip
402
 
403
        mov     eax, [esi+8]
404
        stdcall pci_write8, ebp, ebx, 0x3C, eax
405
.skip:
406
        add     esi, 16
407
        jmp     .iterate
408
 
409
.done:
410
.fail:
411
        pop     ebp
412
        ret
413