Subversion Repositories Kolibri OS

Rev

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

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