Subversion Repositories Kolibri OS

Rev

Rev 2106 | Rev 2166 | 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
 
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
342
; al - IRQ number
343
align 16
344
IRQ_EOI:
345
	test	dword[APIC], 0xffffffff
346
	jnz	.APIC
347
	cmp	al, 8
348
	mov	al, 0x20
349
	jb	@f
350
	out	0xa0, al
351
@@:	out	0x20, al
352
	ret
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