Subversion Repositories Kolibri OS

Rev

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