Subversion Repositories Kolibri OS

Rev

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