Subversion Repositories Kolibri OS

Rev

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

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