Subversion Repositories Kolibri OS

Rev

Rev 2217 | Rev 2229 | 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
 
2130 serge 8
IRQ_RESERVED = 24   ; 16 or 24
1638 serge 9
 
10
iglobal
2219 Serge 11
IRQ_COUNT    dd 24
1638 serge 12
endg
13
 
14
uglobal
2219 Serge 15
irq_mode     rd  1
2212 Serge 16
IOAPIC_base  rd  1
17
LAPIC_BASE   rd  1
1638 serge 18
endg
19
 
2217 Serge 20
APIC_ID         equ 0x20
21
APIC_TPR        equ 0x80
22
APIC_EOI        equ 0xb0
23
APIC_LDR        equ 0xd0
24
APIC_DFR        equ 0xe0
25
APIC_SVR        equ 0xf0
26
APIC_ISR        equ 0x100
27
APIC_ESR        equ 0x280
28
APIC_ICRL       equ 0x300
29
APIC_ICRH       equ 0x310
1638 serge 30
APIC_LVT_LINT0	equ	0x350
31
APIC_LVT_LINT1	equ	0x360
2217 Serge 32
APIC_LVT_err    equ 0x370
1638 serge 33
 
34
; APIC timer
35
APIC_LVT_timer	equ	0x320
36
APIC_timer_div	equ	0x3e0
37
APIC_timer_init	equ	0x380
38
APIC_timer_cur	equ	0x390
39
; IOAPIC
2217 Serge 40
IOAPIC_ID       equ 0x0
41
IOAPIC_VER      equ 0x1
42
IOAPIC_ARB      equ 0x2
43
IOAPIC_REDTBL   equ 0x10
1638 serge 44
 
2217 Serge 45
align 4
1638 serge 46
APIC_init:
2219 Serge 47
        mov [irq_mode], IRQ_PIC
2010 serge 48
 
2219 Serge 49
        cmp [acpi_ioapic_base], 0
50
        jz .no_apic
51
 
52
        cmp [acpi_lapic_base], 0
53
        jz .no_apic
54
 
55
        stdcall load_file, dev_data_path
2217 Serge 56
        test eax, eax
2219 Serge 57
        mov [acpi_dev_data], eax
2217 Serge 58
        jz .no_apic
2212 Serge 59
 
2217 Serge 60
        call  IRQ_mask_all
2010 serge 61
 
2219 Serge 62
; IOAPIC init
2217 Serge 63
        stdcall map_io_mem, [acpi_ioapic_base], 0x20, PG_SW
64
        mov [IOAPIC_base], eax
2010 serge 65
 
2217 Serge 66
        mov eax, IOAPIC_VER
67
        call  IOAPIC_read
68
        shr eax, 16
69
        inc al
70
        movzx eax, al
71
        cmp al, IRQ_RESERVED
72
        jbe @f
73
 
74
        mov al, IRQ_RESERVED
2130 serge 75
@@:
2217 Serge 76
        mov [IRQ_COUNT], eax
1638 serge 77
 
78
	; Reroute IOAPIC & mask all interrupts
2217 Serge 79
        xor ecx, ecx
80
        mov eax, IOAPIC_REDTBL
81
@@:
82
        mov ebx, eax
83
        call  IOAPIC_read
84
        mov ah, 0x09    ; Delivery Mode: Lowest Priority, Destination Mode: Logical
85
        mov al, cl
86
        add al, 0x20    ; vector
87
        or  eax, 0x10000    ; Mask Interrupt
88
        cmp ecx, 16
89
        jb  .set
90
 
91
        or  eax, 0xa000   ;<<< level-triggered active-low for IRQ16+
1638 serge 92
.set:
2217 Serge 93
        xchg  eax, ebx
94
        call  IOAPIC_write
95
        inc eax
96
        mov ebx, eax
97
        call  IOAPIC_read
98
        or  eax, 0xff000000   ; Destination Field
99
        xchg  eax, ebx
100
        call  IOAPIC_write
101
        inc eax
102
        inc ecx
103
        cmp ecx, [IRQ_COUNT]
104
        jb  @b
1638 serge 105
 
2217 Serge 106
        call  LAPIC_init
2010 serge 107
 
2219 Serge 108
        mov [irq_mode], IRQ_APIC
2010 serge 109
 
2217 Serge 110
        mov al, 0x70
111
        out 0x22, al
112
        mov al, 1
113
        out 0x23, al
2010 serge 114
 
2217 Serge 115
.no_apic:
116
 
2049 serge 117
;init handlers table
118
 
2217 Serge 119
        mov ecx, IRQ_RESERVED
120
        mov edi, irqh_tab
2049 serge 121
@@:
2217 Serge 122
        mov eax, edi
123
        stosd
124
        stosd
125
        loop @B
2049 serge 126
 
2217 Serge 127
        mov ecx, 47
128
        mov eax, irqh_pool+IRQH.sizeof
129
        mov [next_irqh], irqh_pool
2049 serge 130
@@:
2217 Serge 131
        mov [eax-IRQH.sizeof], eax
132
        add eax, IRQH.sizeof
133
        loop @B
2049 serge 134
 
2217 Serge 135
        mov [eax-IRQH.sizeof], dword 0
2049 serge 136
 
2217 Serge 137
        ret
2010 serge 138
 
1638 serge 139
;===========================================================
140
align 4
141
LAPIC_init:
142
	; Check MSR support
143
	;....
144
	; Get LAPIC base address
2212 Serge 145
; mov ecx, 0x1b
146
; rdmsr       ; it may be replaced to
147
; and ax, 0xf000    ; mov eax, 0xfee00000
2010 serge 148
 
2217 Serge 149
        stdcall map_io_mem, [acpi_lapic_base], 0x1000, PG_SW
150
        mov [LAPIC_BASE], eax
151
        mov esi, eax
2010 serge 152
 
1638 serge 153
	; Program Destination Format Register for Flat mode.
2217 Serge 154
        mov eax, [esi + APIC_DFR]
155
        or  eax, 0xf0000000
156
        mov [esi + APIC_DFR], eax
2010 serge 157
 
1638 serge 158
	; Program Logical Destination Register.
2217 Serge 159
        mov eax, [esi + APIC_LDR]
160
        ;and  eax, 0xff000000
161
        and eax, 0x00ffffff
162
        or  eax, 0x01000000 ;!!!!!!!!!!!!
163
        mov [esi + APIC_LDR], eax
2010 serge 164
 
1638 serge 165
	; Task Priority Register initialization.
2217 Serge 166
        mov eax, [esi + APIC_TPR]
167
        and eax, 0xffffff00
168
        mov [esi + APIC_TPR], eax
1638 serge 169
 
170
	; Flush the queue
2217 Serge 171
        mov edx, 0
172
.nxt2:
173
        mov ecx, 32
174
        mov eax, [esi + APIC_ISR + edx]
175
.nxt:
176
        shr eax, 1
177
        jnc @f
178
        mov dword [esi + APIC_EOI], 0 ; EOI
179
@@:
180
        loop  .nxt
1638 serge 181
 
2217 Serge 182
        add edx, 0x10
183
        cmp edx, 0x170
184
        jbe .nxt2
185
 
1638 serge 186
	; Spurious-Interrupt Vector Register initialization.
2217 Serge 187
        mov eax, [esi + APIC_SVR]
188
        or  eax, 0x1ff
189
        and eax, 0xfffffdff
190
        mov [esi + APIC_SVR], eax
1638 serge 191
 
192
	; Initialize LVT LINT0 register. (INTR)
2217 Serge 193
        mov eax, 0x00700
194
        ; mov eax, 0x10700
195
        mov [esi + APIC_LVT_LINT0], eax
1638 serge 196
 
197
	; Initialize LVT LINT1 register. (NMI)
2217 Serge 198
        mov eax, 0x00400
199
        mov [esi + APIC_LVT_LINT1], eax
1638 serge 200
 
201
	; Initialize LVT Error register.
2217 Serge 202
        mov eax, [esi + APIC_LVT_err]
203
        or  eax, 0x10000    ; bit 16
204
        mov [esi + APIC_LVT_err], eax
2010 serge 205
 
1638 serge 206
	; LAPIC timer
207
	; pre init
2217 Serge 208
        mov dword[esi + APIC_timer_div], 1011b  ; 1
209
        mov dword[esi + APIC_timer_init], 0xffffffff  ; max val
210
        push  esi
211
        mov esi, 640        ; wait 0.64 sec
212
        call  delay_ms
213
        pop esi
214
        mov eax, [esi + APIC_timer_cur]   ; read current tick couner
215
        xor eax, 0xffffffff       ; eax = 0xffffffff - eax
216
        shr eax, 6          ; eax /= 64; APIC ticks per 0.01 sec
2010 serge 217
 
1638 serge 218
	; Start (every 0.01 sec)
2217 Serge 219
        mov dword[esi + APIC_LVT_timer], 0x30020  ; periodic int 0x20
220
        mov dword[esi + APIC_timer_init], eax
221
        ret
2010 serge 222
 
1638 serge 223
;===========================================================
224
; IOAPIC implementation
225
align 4
226
IOAPIC_read:
227
; in : EAX - IOAPIC register
228
; out: EAX - readed value
2217 Serge 229
        push  esi
230
        mov esi, [IOAPIC_base]
231
        mov [esi], eax
232
        mov eax, [esi + 0x10]
233
        pop esi
234
        ret
235
 
1638 serge 236
align 4
237
IOAPIC_write:
238
; in :	EAX - IOAPIC register
239
;	EBX - value
240
; out:	none
2217 Serge 241
        push  esi
242
        mov esi, [IOAPIC_base]
243
        mov [esi], eax
244
        mov [esi + 0x10], ebx
245
        pop esi
246
        ret
1638 serge 247
;===========================================================
248
; Remap all IRQ to 0x20+ Vectors
249
; IRQ0 to vector 0x20, IRQ1 to vector 0x21....
2219 Serge 250
align 4
1638 serge 251
PIC_init:
2217 Serge 252
        cli
253
        mov al,0x11   ;  icw4, edge triggered
254
        out 0x20,al
255
        out 0xA0,al
1638 serge 256
 
2217 Serge 257
        mov al,0x20   ;  generate 0x20 +
258
        out 0x21,al
259
        mov al,0x28   ;  generate 0x28 +
260
        out 0xA1,al
1638 serge 261
 
2217 Serge 262
        mov al,0x04   ;  slave at irq2
263
        out 0x21,al
264
        mov al,0x02   ;  at irq9
265
        out 0xA1,al
1638 serge 266
 
2217 Serge 267
        mov al,0x01   ;  8086 mode
268
        out 0x21,al
269
        out 0xA1,al
1638 serge 270
 
2217 Serge 271
        call  IRQ_mask_all
1638 serge 272
	; mov	dword[irq_type_to_set], IRQ_TYPE_PIC
2217 Serge 273
        ret
1638 serge 274
 
275
; -----------------------------------------
276
; TIMER SET TO 1/100 S
2219 Serge 277
align 4
1638 serge 278
PIT_init:
2217 Serge 279
        mov   al,0x34      ; set to 100Hz
280
        out   0x43,al
281
        mov   al,0x9b      ; lsb    1193180 / 1193
282
        out   0x40,al
283
        mov   al,0x2e      ; msb
284
        out   0x40,al
285
        ret
1638 serge 286
 
287
; -----------------------------------------
2219 Serge 288
align 4
1638 serge 289
unmask_timer:
2219 Serge 290
        cmp  [irq_mode], IRQ_APIC
291
        je @f
292
 
2217 Serge 293
        stdcall enable_irq, 0
294
        ret
2049 serge 295
@@:
1638 serge 296
	; use PIT
297
	; in some systems PIT no connected to IOAPIC
298
	; mov	eax, 0x14
299
	; call	IOAPIC_read
300
	; mov	ah, 0x09		; Delivery Mode: Lowest Priority, Destination Mode: Logical
301
	; mov	al, 0x20
302
	; or	eax, 0x10000		; Mask Interrupt
303
	; mov	ebx, eax
304
	; mov	eax, 0x14
305
	; call	IOAPIC_write
306
	; stdcall enable_irq, 2
307
	; ret
2049 serge 308
 
1638 serge 309
	; use LAPIC timer
2217 Serge 310
        mov esi, [LAPIC_BASE]
311
        mov eax, [esi + APIC_LVT_timer]
312
        and eax, 0xfffeffff
313
        mov [esi + APIC_LVT_timer], eax
314
        ret
1638 serge 315
 
316
; -----------------------------------------
317
; Disable all IRQ
2219 Serge 318
align 4
1638 serge 319
IRQ_mask_all:
2219 Serge 320
        cmp [irq_mode], IRQ_APIC
321
        je .APIC
322
 
2217 Serge 323
        mov al, 0xFF
324
        out 0x21, al
325
        out 0xA1, al
326
        mov ecx,0x1000
327
        ret
1638 serge 328
.APIC:
2217 Serge 329
        mov ecx, [IRQ_COUNT]
330
        mov eax, 0x10
331
@@:
332
        mov ebx, eax
333
        call  IOAPIC_read
334
        or  eax, 0x10000    ; bit 16
335
        xchg  eax, ebx
336
        call  IOAPIC_write
337
        inc eax
338
        inc eax
339
        loop  @b
340
        ret
341
 
1638 serge 342
; -----------------------------------------
343
; End Of Interrupt
2166 serge 344
; cl - IRQ number
2219 Serge 345
align 4
2166 serge 346
irq_eoi:         ; __fastcall
2219 Serge 347
        cmp [irq_mode], IRQ_APIC
348
        je .APIC
2217 Serge 349
 
350
        cmp cl, 8
351
        mov al, 0x20
352
        jb  @f
353
        out 0xa0, al
2166 serge 354
@@:
2217 Serge 355
        out 0x20, al
356
        ret
2166 serge 357
 
2049 serge 358
.APIC:
2217 Serge 359
        mov eax, [LAPIC_BASE]
360
        mov dword [eax + APIC_EOI], 0 ; EOI
361
        ret
2049 serge 362
 
1638 serge 363
; -----------------------------------------
364
; from dll.inc
365
align 4
366
proc enable_irq stdcall, irq_line:dword
2217 Serge 367
        mov ebx, [irq_line]
2219 Serge 368
        cmp [irq_mode], IRQ_APIC
369
        je .APIC
2217 Serge 370
 
371
        mov edx, 0x21
372
        cmp ebx, 8
373
        jb  @F
374
 
375
        mov edx, 0xA1
376
        sub ebx,8
1638 serge 377
@@:
2217 Serge 378
        in  al,dx
379
        btr eax, ebx
380
        out dx, al
381
        ret
1638 serge 382
.APIC:
2217 Serge 383
        shl ebx, 1
384
        add ebx, 0x10
385
        mov eax, ebx
386
        call  IOAPIC_read
387
        and eax, 0xfffeffff   ; bit 16
388
        xchg  eax, ebx
389
        call  IOAPIC_write
390
        ret
1638 serge 391
endp
392
 
2219 Serge 393
align 4
394
pci_irq_fixup:
1638 serge 395
 
2219 Serge 396
        push ebp
1638 serge 397
 
2219 Serge 398
        mov esi, [acpi_dev_data]
399
        mov ebx, [acpi_dev_size]
400
 
401
        lea edi, [esi+ebx]
402
 
403
.iterate:
404
 
405
        cmp esi, edi
406
        jae .done
407
 
408
        mov eax, [esi]
409
 
410
        cmp eax, -1
411
        je .done
412
 
413
        movzx ebx, al
414
        movzx ebp, ah
415
 
416
        stdcall pci_read32, ebp, ebx, 0
417
 
418
        cmp eax, [esi+4]
419
        jne .skip
420
 
421
        mov eax, [esi+8]
422
        stdcall pci_write8, ebp, ebx, 0x3C, eax
423
.skip:
424
        add esi, 16
425
        jmp .iterate
426
 
427
.done:
428
.fail:
429
        pop ebp
430
        ret
431
 
432
 
1638 serge 433
; IRQ_TYPE_DISABLE	equ	0
434
; IRQ_TYPE_PIC		equ	1
435
; IRQ_TYPE_APIC		equ	2
436
 
437
; uglobal
438
; irq_type_to_set	rd	1
439
; irq_types	rd	IRQ_RESERVE
440
; endg
441
 
442
; -----------------------------------------
443
; End Of Interrupt
444
; al - IRQ number
445
; align 16
446
; IRQ_EOI:
447
	; movzx	eax, al
448
	; cmp	dword[irq_types + eax * 4], IRQ_TYPE_APIC
449
	; jne	@f
450
	; mov	eax, [LAPIC_BASE]
451
	; mov	dword [eax + APIC_EOI], 0	; EOI
452
	; ret
453
; @@:
454
	; cmp	al, 8
455
	; mov	al, 0x20
456
	; jb	@f
457
	; out	0xa0, al
458
; @@:	out	0x20, al
459
	; ret
460
 
461
; align 4
462
; proc enable_irq stdcall, irq_line:dword
463
	; cmp	dword[irq_type_to_set], IRQ_TYPE_APIC
464
	; jne	@f
465
	; stdcall	APIC_enable_irq, [irq_line]
466
	; ret
467
; @@:	stdcall	PIC_enable_irq, [irq_line]
468
	; ret
469
; endp
470
 
471
; align 4
472
; proc disable_irq stdcall, irq_line:dword
473
	; push	eax
474
	; mov	eax, [irq_line]
475
	; cmp	dword[irq_types + eax * 4], IRQ_TYPE_APIC
476
	; jne	@f
477
	; stdcall	APIC_disable_irq, eax
478
	; pop	eax
479
	; ret
480
; @@:	stdcall	PIC_disable_irq, eax
481
	; pop	eax
482
	; ret
483
; endp
484
 
485
; align 4
486
; proc PIC_enable_irq stdcall, irq_line:dword
487
	; pusha
488
	; mov	ebx, [irq_line]
489
	; mov	eax, [irq_types + ebx * 4]
490
	; cmp	eax, IRQ_TYPE_DISABLE
491
	; je	@f
492
	; cmp	eax, IRQ_TYPE_PIC
493
	; je	@f
494
	; stdcall	disable_irq, ebx
495
; @@:	mov	dword[irq_types + ebx * 4], IRQ_TYPE_PIC
496
	; mov	edx, 0x21
497
	; cmp	ebx, 8
498
	; jb	@F
499
	; mov	edx, 0xA1
500
	; sub	ebx,8
501
; @@:	in	al,dx
502
	; btr	eax, ebx
503
	; out	dx, al
504
	; popa
505
	; ret
506
; endp
507
 
508
; align 4
509
; proc PIC_disable_irq stdcall, irq_line:dword
510
	; pusha
511
	; mov	ebx, [irq_line]
512
	; mov	dword[irq_types + ebx * 4], IRQ_TYPE_DISABLE
513
	; mov	edx, 0x21
514
	; cmp	ebx, 8
515
	; jb	@F
516
	; mov	edx, 0xA1
517
	; sub	ebx,8
518
; @@:	in	al,dx
519
	; bts	eax, ebx
520
	; out	dx, al
521
	; popa
522
	; ret
523
; endp
524
 
525
; align 4
526
; proc APIC_enable_irq stdcall, irq_line:dword
527
	; pusha
528
	; mov	ebx, [irq_line]
529
	; mov	eax, [irq_types + ebx * 4]
530
	; cmp	eax, IRQ_TYPE_DISABLE
531
	; je	@f
532
	; cmp	eax, IRQ_TYPE_APIC
533
	; je	@f
534
	; stdcall	disable_irq, ebx
535
; @@:	mov	dword[irq_types + ebx * 4], IRQ_TYPE_APIC
536
	; shl	ebx, 1
537
	; add	ebx, 0x10
538
	; mov	eax, ebx
539
	; call	IOAPIC_read
540
	; and	eax, 0xfffeffff		; bit 16
541
	; xchg	eax, ebx
542
	; call	IOAPIC_write
543
	; popa
544
	; ret
545
; endp
546
 
547
; align 4
548
; proc APIC_disable_irq stdcall, irq_line:dword
549
	; pusha
550
	; mov	ebx, [irq_line]
551
	; mov	dword[irq_types + ebx * 4], IRQ_TYPE_DISABLE
552
	; shl	ebx, 1
553
	; add	ebx, 0x10
554
	; mov	eax, ebx
555
	; call	IOAPIC_read
556
	; or	eax, 0x10000
557
	; xchg	eax, ebx
558
	; call	IOAPIC_write
559
	; popa
560
	; ret
561
; endp
2049 serge 562