Subversion Repositories Kolibri OS

Rev

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