Subversion Repositories Kolibri OS

Rev

Rev 6942 | Rev 7733 | 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: 7136 $
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
 
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:
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
5791 serge 450
        push    esi
5787 serge 451
        pushfd
452
        cli
2288 clevermous 453
 
5787 serge 454
        mov     ebx, eax
455
@@:
456
        mov     edx, [ebx+0xF4]
457
        mov     eax, [ebx+0xF0]
458
        mov     ecx, [ebx+0xF4]
459
        cmp     ecx, edx
5791 serge 460
        jne     @B
6941 serge 461
        popfd
2288 clevermous 462
 
6942 serge 463
;96-bit arithmetic
464
;ebx - low dword
465
;esi - medium dword
466
;edx - high dword
467
 
5791 serge 468
        mul     [hpet_period]
469
        mov     ebx, eax
470
        mov     esi, edx
471
 
472
        mov     eax, ecx
473
        mul     [hpet_period]
6942 serge 474
        add     esi, eax
475
        adc     edx, 0
6941 serge 476
        mov     eax, ebx
6942 serge 477
        mov     ebx, esi
478
        shrd    eax, ebx, 10
479
        shrd    esi, edx, 10
480
        mov     edx, esi
5791 serge 481
 
482
        pop     esi
5787 serge 483
        pop     ebx
484
        ret
485
 
486
.old_tics:
487
        mov     eax, [timer_ticks]
488
        mov     edx, 10000000
489
        mul     edx
490
        ret
491
 
6590 serge 492
align 4
493
acpi_get_root_ptr:
494
        mov     eax, [acpi_rsdp]
495
        ret