Subversion Repositories Kolibri OS

Rev

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

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