Subversion Repositories Kolibri OS

Rev

Rev 2166 | Rev 2212 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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