Subversion Repositories Kolibri OS

Rev

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