Subversion Repositories Kolibri OS

Rev

Rev 9977 | Details | Compare with Previous | Last modification | View Log | RSS feed

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