Subversion Repositories Kolibri OS

Rev

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