Subversion Repositories Kolibri OS

Rev

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