Subversion Repositories Kolibri OS

Rev

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

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