Subversion Repositories Kolibri OS

Rev

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

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