Subversion Repositories Kolibri OS

Rev

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