xref: /original-bsd/sys/i386/isa/icu.s (revision 753853ba)
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * William Jolitz.
7 *
8 * %sccs.include.386.c%
9 *
10 *	@(#)icu.s	7.4 (Berkeley) 02/28/92
11 */
12
13/*
14 * AT/386
15 * Vector interrupt control section
16 * Copyright (C) 1989,90 W. Jolitz
17 */
18
19	.data
20	.globl	_imen
21	.globl	_cpl
22_cpl:	.long	0xffff			# current priority level (all off)
23_imen:	.long	0xffff			# interrupt mask enable (all off)
24	.globl	_highmask
25_highmask:	.long	0xffff
26	.globl	_ttymask
27_ttymask:	.long	0
28	.globl	_biomask
29_biomask:	.long	0
30	.globl	_netmask
31_netmask:	.long	0
32	.globl	_isa_intr
33_isa_intr:	.space	16*4
34
35	.text
36/*
37 * Handle return from interrupt after device handler finishes
38 */
39doreti:
40	cli
41	popl	%ebx			# remove intr number
42	nop
43	popl	%eax			# get previous priority
44	nop
45	# now interrupt frame is a trap frame!
46	movw	%ax,%cx
47	movw	%ax,_cpl
48	orw	_imen,%ax
49	outb	%al,$ IO_ICU1+1		# re-enable intr?
50	movb	%ah,%al
51	outb	%al,$ IO_ICU2+1
52
53	# andw	$0xffff,%cx
54	cmpw	$0,%cx			# returning to zero?
55	je	1f
56
572:	popl	%es			# nope, going to non-zero level
58	nop
59	popl	%ds
60	nop
61	popal
62	nop
63	addl	$8,%esp
64	iret
65
661:	cmpl	$0,_netisr		# check for softint s/traps
67	je	2b
68
69#include "../net/netisr.h"
70
711:
72
73#define DONET(s, c)	; \
74	.globl	c ;  \
75	btrl	$ s ,_netisr ;  \
76	jnb	1f ; \
77	call	c ; \
781:
79
80	call	_splnet
81	pushl	%eax
82
83
84	DONET(NETISR_RAW,_rawintr)
85#ifdef INET
86	DONET(NETISR_IP,_ipintr)
87	DONET(NETISR_ARP,_arpintr)
88#endif
89#ifdef IMP
90	DONET(NETISR_IMP,_impintr)
91#endif
92#ifdef NS
93	DONET(NETISR_NS,_nsintr)
94#endif
95#ifdef ISO
96	DONET(NETISR_ISO,_clnlintr)
97#endif
98#ifdef CCITT
99	DONET(NETISR_CCITT,_hdintr)
100#endif
101
102	/* restore interrupt state, but don't turn them on just yet */
103	cli
104	popl	%eax
105	nop
106	movw	%ax,_cpl
107	orw	_imen,%ax
108	outb	%al,$ IO_ICU1+1		# re-enable intr?
109	movb	%ah,%al
110	outb	%al,$ IO_ICU2+1
111
112	btrl	$ NETISR_SCLK,_netisr
113	jnb	1f
114	# back to an interrupt frame for a moment
115	call	_splsoftclock
116	pushl	%eax
117	pushl	$0xff	# dummy intr
118	call	_softclock
119	popl	%eax
120	nop
121	call	_splx
122	popl	%eax
123	nop
124
125	jmp	2f
126
1271:
128	cmpw	$0x1f,13*4(%esp)	# to user?
129	jne	2f			# nope, leave
130	btrl	$ NETISR_AST ,_netisr
131	jnb	2f
132	call	_trap
133
1342:	pop	%es
135	nop
136	pop	%ds
137	nop
138	popal
139	nop
140	addl	$8,%esp
141	iret
142
143/*
144 * Interrupt priority mechanism
145 *
146 * Two flavors	-- imlXX masks relative to ISA noemenclature (for PC compat sw)
147 *		-- splXX masks with group mechanism for BSD purposes
148 */
149
150	.globl	_splhigh
151	.globl	_splclock
152_splhigh:
153_splclock:
154	cli				# disable interrupts
155	movw	$0xffff,%ax		# set new priority level
156	movw	%ax,%dx
157	# orw	_imen,%ax		# mask off those not enabled yet
158	movw	%ax,%cx
159	outb	%al,$ IO_ICU1+1		/* update icu's */
160	movb	%ah,%al
161	outb	%al,$ IO_ICU2+1
162	movzwl	_cpl,%eax		# return old priority
163	movw	%dx,_cpl		# set new priority level
164	sti				# enable interrupts
165	ret
166
167	.globl	_spltty			# block clists
168_spltty:
169	cli				# disable interrupts
170	movw	_cpl,%ax
171	orw	_ttymask,%ax
172	movw	%ax,%dx
173	orw	_imen,%ax		# mask off those not enabled yet
174	movw	%ax,%cx
175	outb	%al,$ IO_ICU1+1		/* update icu's */
176	movb	%ah,%al
177	outb	%al,$ IO_ICU2+1
178	movzwl	_cpl,%eax		# return old priority
179	movw	%dx,_cpl		# set new priority level
180	sti				# enable interrupts
181	ret
182
183	.globl	_splimp
184	.globl	_splnet
185_splimp:
186_splnet:
187	cli				# disable interrupts
188	movw	_cpl,%ax
189	orw	_netmask,%ax
190	movw	%ax,%dx
191	orw	_imen,%ax		# mask off those not enabled yet
192	movw	%ax,%cx
193	outb	%al,$ IO_ICU1+1		/* update icu's */
194	movb	%ah,%al
195	outb	%al,$ IO_ICU2+1
196	movzwl	_cpl,%eax		# return old priority
197	movw	%dx,_cpl		# set new priority level
198	sti				# enable interrupts
199	ret
200
201	.globl	_splbio
202_splbio:
203	cli				# disable interrupts
204	movw	_cpl,%ax
205	orw	_biomask,%ax
206	movw	%ax,%dx
207	orw	_imen,%ax		# mask off those not enabled yet
208	movw	%ax,%cx
209	outb	%al,$ IO_ICU1+1		/* update icu's */
210	movb	%ah,%al
211	outb	%al,$ IO_ICU2+1
212	movzwl	_cpl,%eax		# return old priority
213	movw	%dx,_cpl		# set new priority level
214	sti				# enable interrupts
215	ret
216
217	.globl	_splsoftclock
218_splsoftclock:
219	cli				# disable interrupts
220	movw	_cpl,%ax
221	orw	$0x8000,%ax		# set new priority level
222	movw	%ax,%dx
223	orw	_imen,%ax		# mask off those not enabled yet
224	movw	%ax,%cx
225	outb	%al,$ IO_ICU1+1		/* update icu's */
226	movb	%ah,%al
227	outb	%al,$ IO_ICU2+1
228	movzwl	_cpl,%eax		# return old priority
229	movw	%dx,_cpl		# set new priority level
230	sti				# enable interrupts
231	ret
232
233	.globl _splnone
234	.globl _spl0
235_splnone:
236_spl0:
237	cli				# disable interrupts
238	pushl	_cpl			# save old priority
239	movw	_cpl,%ax
240	orw	_netmask,%ax		# mask off those network devices
241	movw	%ax,_cpl		# set new priority level
242	orw	_imen,%ax		# mask off those not enabled yet
243	outb	%al,$ IO_ICU1+1		/* update icu's */
244	movb	%ah,%al
245	outb	%al,$ IO_ICU2+1
246	sti				# enable interrupts
247
248	DONET(NETISR_RAW,_rawintr)
249#ifdef INET
250	DONET(NETISR_IP,_ipintr)
251	DONET(NETISR_ARP,_arpintr)
252#endif
253#ifdef IMP
254	DONET(NETISR_IMP,_impintr)
255#endif
256#ifdef NS
257	DONET(NETISR_NS,_nsintr)
258#endif
259#ifdef ISO
260	DONET(NETISR_ISO,_clnlintr)
261#endif
262#ifdef CCITT
263	DONET(NETISR_CCITT,_hdintr)
264#endif
265
266	cli				# disable interrupts
267	popl	_cpl			# save old priority
268	nop
269
270	movw	$0,%ax			# set new priority level
271	movw	%ax,%dx
272	orw	_imen,%ax		# mask off those not enabled yet
273	movw	%ax,%cx
274	outb	%al,$ IO_ICU1+1		/* update icu's */
275	movb	%ah,%al
276	outb	%al,$ IO_ICU2+1
277	movzwl	_cpl,%eax		# return old priority
278	movw	%dx,_cpl		# set new priority level
279	sti				# enable interrupts
280	ret
281
282	.globl _splx
283_splx:
284	cli				# disable interrupts
285	movw	4(%esp),%ax		# new priority level
286	movw	%ax,%dx
287	cmpw	$0,%dx
288	je	_spl0			# going to "zero level" is special
289
290	orw	_imen,%ax		# mask off those not enabled yet
291	movw	%ax,%cx
292	outb	%al,$ IO_ICU1+1		/* update icu's */
293	movb	%ah,%al
294	outb	%al,$ IO_ICU2+1
295	movzwl	_cpl,%eax		# return old priority
296	movw	%dx,_cpl		# set new priority level
297	sti				# enable interrupts
298	ret
299
300	/* hardware interrupt catcher (IDT 32 - 47) */
301	.globl	_isa_strayintr
302
303IDTVEC(intr0)
304	INTR(0, _highmask, 0) ; call	_isa_strayintr ; INTREXIT1
305
306IDTVEC(intr1)
307	INTR(1, _highmask, 1) ; call	_isa_strayintr ; INTREXIT1
308
309IDTVEC(intr2)
310	INTR(2, _highmask, 2) ; call	_isa_strayintr ; INTREXIT1
311
312IDTVEC(intr3)
313	INTR(3, _highmask, 3) ; call	_isa_strayintr ; INTREXIT1
314
315IDTVEC(intr4)
316	INTR(4, _highmask, 4) ; call	_isa_strayintr ; INTREXIT1
317
318IDTVEC(intr5)
319	INTR(5, _highmask, 5) ; call	_isa_strayintr ; INTREXIT1
320
321IDTVEC(intr6)
322	INTR(6, _highmask, 6) ; call	_isa_strayintr ; INTREXIT1
323
324IDTVEC(intr7)
325	INTR(7, _highmask, 7) ; call	_isa_strayintr ; INTREXIT1
326
327
328IDTVEC(intr8)
329	INTR(8, _highmask, 8) ; call	_isa_strayintr ; INTREXIT2
330
331IDTVEC(intr9)
332	INTR(9, _highmask, 9) ; call	_isa_strayintr ; INTREXIT2
333
334IDTVEC(intr10)
335	INTR(10, _highmask, 10) ; call	_isa_strayintr ; INTREXIT2
336
337IDTVEC(intr11)
338	INTR(11, _highmask, 11) ; call	_isa_strayintr ; INTREXIT2
339
340IDTVEC(intr12)
341	INTR(12, _highmask, 12) ; call	_isa_strayintr ; INTREXIT2
342
343IDTVEC(intr13)
344	INTR(13, _highmask, 13) ; call	_isa_strayintr ; INTREXIT2
345
346IDTVEC(intr14)
347	INTR(14, _highmask, 14) ; call	_isa_strayintr ; INTREXIT2
348
349IDTVEC(intr15)
350	INTR(15, _highmask, 15) ; call	_isa_strayintr ; INTREXIT2
351
352