Subversion Repositories Kolibri OS

Rev

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

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