xref: /original-bsd/sys/i386/isa/icu.s (revision 95a66346)
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	5.5 (Berkeley) 01/08/91
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
33	.text
34/*
35 * Handle return from interrupt after device handler finishes
36 */
37doreti:
38	cli
39	popl	%ebx			# remove intr number
40	popl	%eax			# get previous priority
41	# now interrupt frame is a trap frame!
42	movw	%ax,%cx
43	movw	%ax,_cpl
44	orw	_imen,%ax
45	NOP
46	outb	%al,$ IO_ICU1+1		# re-enable intr?
47	NOP
48	movb	%ah,%al
49	NOP
50	outb	%al,$ IO_ICU2+1
51	NOP
52
53	andw	$0xffff,%cx
54	cmpw	$0,%cx			# returning to zero?
55	je	1f
56
57	pop	%es			# nope, going to non-zero level
58	pop	%ds
59	popa
60	addl	$8,%esp
61	iret
62
631:	cmpl	$0,_netisr		# check for softint s/traps
64	jne	1f
65
66	pop	%es			# none, going back to base pri
67	pop	%ds
68	popa
69	addl	$8,%esp
70	iret
71
72#include "../net/netisr.h"
73
741:
75
76#define DONET(s, c)	; \
77	.globl	c ;  \
78	movl	$ s ,%eax ; 	\
79	btrl	%eax,_netisr ;  \
80	jnb	1f ; \
81	call	c ; \
821:
83
84	call	_splnet
85	pushl	%eax
86
87	DONET(NETISR_RAW,_rawintr)
88#ifdef INET
89	DONET(NETISR_IP,_ipintr)
90#endif
91#ifdef IMP
92	DONET(NETISR_IMP,_impintr)
93#endif
94#ifdef NS
95	DONET(NETISR_NS,_nsintr)
96#endif
97
98	popl	%eax
99	movw	%ax,_cpl
100	orw	_imen,%ax
101	NOP
102	outb	%al,$ IO_ICU1+1		# re-enable intr?
103	NOP
104	movb	%ah,%al
105	NOP
106	outb	%al,$ IO_ICU2+1
107	NOP
108
109	# btrl	$ NETISR_SCLK,_netisr
110	movl	$ NETISR_SCLK,%eax	# stupid assembler, as usual
111	btrl	%eax,_netisr
112	jnb	1f
113	# back to an interrupt frame for a moment
114	call	_splsoftclock
115	pushl	%eax
116	pushl	$0xff	# dummy intr
117	call	_softclock
118	popl	%eax
119	call	_splx
120	popl	%eax
121
122	jmp	2f
123
124	/* 1:	btrl	$NETISR_AST,_netisr*/
1251:
126	cmpw	$0x1f,13*4(%esp)	# to user?
127	jne	2f			# nope, leave
128	movl	$ NETISR_AST,%eax	# stupid assembler, as usual
129	btrl	%eax,_netisr
130	jnb	2f
131	call	_trap
132
1332:	pop	%es
134	pop	%ds
135	popal
136	addl	$8,%esp
137	iret
138
139/*
140 * Interrupt priority mechanism
141 *
142 * Two flavors	-- imlXX masks relative to ISA noemenclature (for PC compat sw)
143 *		-- splXX masks with group mechanism for BSD purposes
144 */
145
146	.globl	_splhigh
147	.globl	_splclock
148_splhigh:
149_splclock:
150	cli				# disable interrupts
151	movw	$0xffff,%ax		# set new priority level
152	movw	%ax,%dx
153	# orw	_imen,%ax		# mask off those not enabled yet
154	movw	%ax,%cx
155	NOP
156	outb	%al,$ IO_ICU1+1		/* update icu's */
157	NOP
158	movb	%ah,%al
159	NOP
160	outb	%al,$ IO_ICU2+1
161	NOP
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	NOP
176	outb	%al,$ IO_ICU1+1		/* update icu's */
177	NOP
178	movb	%ah,%al
179	NOP
180	outb	%al,$ IO_ICU2+1
181	NOP
182	movzwl	_cpl,%eax		# return old priority
183	movw	%dx,_cpl		# set new priority level
184	sti				# enable interrupts
185	ret
186
187	.globl	_splimp
188	.globl	_splnet
189_splimp:
190_splnet:
191	cli				# disable interrupts
192	movw	_cpl,%ax
193	orw	_netmask,%ax
194	movw	%ax,%dx
195	orw	_imen,%ax		# mask off those not enabled yet
196	movw	%ax,%cx
197	NOP
198	outb	%al,$ IO_ICU1+1		/* update icu's */
199	NOP
200	movb	%ah,%al
201	NOP
202	outb	%al,$ IO_ICU2+1
203	NOP
204	movzwl	_cpl,%eax		# return old priority
205	movw	%dx,_cpl		# set new priority level
206	sti				# enable interrupts
207	ret
208
209	.globl	_splbio
210_splbio:
211	cli				# disable interrupts
212	movw	_cpl,%ax
213	orw	_biomask,%ax
214	movw	%ax,%dx
215	orw	_imen,%ax		# mask off those not enabled yet
216	movw	%ax,%cx
217	NOP
218	outb	%al,$ IO_ICU1+1		/* update icu's */
219	NOP
220	movb	%ah,%al
221	NOP
222	outb	%al,$ IO_ICU2+1
223	NOP
224	movzwl	_cpl,%eax		# return old priority
225	movw	%dx,_cpl		# set new priority level
226	sti				# enable interrupts
227	ret
228
229	.globl	_splsoftclock
230_splsoftclock:
231	cli				# disable interrupts
232	movw	_cpl,%ax
233	orw	$0x8000,%ax		# set new priority level
234	movw	%ax,%dx
235	orw	_imen,%ax		# mask off those not enabled yet
236	movw	%ax,%cx
237	NOP
238	outb	%al,$ IO_ICU1+1		/* update icu's */
239	NOP
240	movb	%ah,%al
241	NOP
242	outb	%al,$ IO_ICU2+1
243	NOP
244	movzwl	_cpl,%eax		# return old priority
245	movw	%dx,_cpl		# set new priority level
246	sti				# enable interrupts
247	ret
248
249	.globl _splnone
250	.globl _spl0
251_splnone:
252_spl0:
253	cli				# disable interrupts
254	pushl	_cpl			# save old priority
255	movw	_cpl,%ax
256	orw	_netmask,%ax		# mask off those network devices
257	movw	%ax,_cpl		# set new priority level
258	orw	_imen,%ax		# mask off those not enabled yet
259	NOP
260	outb	%al,$ IO_ICU1+1		/* update icu's */
261	NOP
262	movb	%ah,%al
263	NOP
264	outb	%al,$ IO_ICU2+1
265	NOP
266	sti				# enable interrupts
267
268	DONET(NETISR_RAW,_rawintr)
269#ifdef INET
270	DONET(NETISR_IP,_ipintr)
271#endif
272	cli				# disable interrupts
273	popl	_cpl			# save old priority
274	movw	$0,%ax			# set new priority level
275	movw	%ax,%dx
276	orw	_imen,%ax		# mask off those not enabled yet
277	movw	%ax,%cx
278	NOP
279	outb	%al,$ IO_ICU1+1		/* update icu's */
280	NOP
281	movb	%ah,%al
282	NOP
283	outb	%al,$ IO_ICU2+1
284	NOP
285	movzwl	_cpl,%eax		# return old priority
286	movw	%dx,_cpl		# set new priority level
287	sti				# enable interrupts
288	ret
289
290	.globl _splx
291_splx:
292	cli				# disable interrupts
293	movw	4(%esp),%ax		# new priority level
294	movw	%ax,%dx
295	cmpw	$0,%dx
296	je	_spl0			# going to "zero level" is special
297
298	orw	_imen,%ax		# mask off those not enabled yet
299	movw	%ax,%cx
300	NOP
301	outb	%al,$ IO_ICU1+1		/* update icu's */
302	NOP
303	movb	%ah,%al
304	NOP
305	outb	%al,$ IO_ICU2+1
306	NOP
307	movzwl	_cpl,%eax		# return old priority
308	movw	%dx,_cpl		# set new priority level
309	sti				# enable interrupts
310	ret
311
312#ifdef notyet
313	.globl	_iml8			# mask off all but irq0-1
314_iml8:
315	cli				# disable interrupts
316	movw	$0xfffc,%ax		# set new priority level
317	movw	%ax,%dx
318	orw	_imen,%ax		# mask off those not enabled yet
319	movw	%ax,%cx
320	NOP
321	outb	%al,$ IO_ICU1+1		/* update icu's */
322	NOP
323	movb	%ah,%al
324	NOP
325	outb	%al,$ IO_ICU2+1
326	NOP
327	movzwl	_cpl,%eax		# return old priority
328	movw	%dx,_cpl		# set new priority level
329	sti				# enable interrupts
330	ret
331
332	.globl	_iml10			# mask off all but irq0-1,8-9
333_iml10:
334	cli				# disable interrupts
335	movw	$0xfcf8,%ax		# set new priority level
336	movw	%ax,%dx
337	orw	_imen,%ax		# mask off those not enabled yet
338	movw	%ax,%cx
339	NOP
340	outb	%al,$ IO_ICU1+1		/* update icu's */
341	NOP
342	movb	%ah,%al
343	NOP
344	outb	%al,$ IO_ICU2+1
345	NOP
346	movzwl	_cpl,%eax		# return old priority
347	movw	%dx,_cpl		# set new priority level
348	sti				# enable interrupts
349	ret
350
351	.globl	_iml11			# mask off all but irq0-1,8-10
352_iml11:
353	cli				# disable interrupts
354	movw	$0xf8f8,%ax		# set new priority level
355	movw	%ax,%dx
356	orw	_imen,%ax		# mask off those not enabled yet
357	movw	%ax,%cx
358	NOP
359	outb	%al,$ IO_ICU1+1		/* update icu's */
360	NOP
361	movb	%ah,%al
362	NOP
363	outb	%al,$ IO_ICU2+1
364	NOP
365	movzwl	_cpl,%eax		# return old priority
366	movw	%dx,_cpl		# set new priority level
367	sti				# enable interrupts
368	ret
369
370	.globl	_iml12			# mask off all but irq0-1,8-11
371_iml12:
372	cli				# disable interrupts
373	movw	$0xf0f8,%ax		# set new priority level
374	movw	%ax,%dx
375	orw	_imen,%ax		# mask off those not enabled yet
376	movw	%ax,%cx
377	NOP
378	outb	%al,$ IO_ICU1+1		/* update icu's */
379	NOP
380	movb	%ah,%al
381	NOP
382	outb	%al,$ IO_ICU2+1
383	NOP
384	movzwl	_cpl,%eax		# return old priority
385	movw	%dx,_cpl		# set new priority level
386	sti				# enable interrupts
387	ret
388
389	.globl	_iml13			# mask off all but irq0-1,8-12
390_iml13:
391	cli				# disable interrupts
392	movw	$0xe0f8,%ax		# set new priority level
393	movw	%ax,%dx
394	orw	_imen,%ax		# mask off those not enabled yet
395	movw	%ax,%cx
396	NOP
397	outb	%al,$ IO_ICU1+1		/* update icu's */
398	NOP
399	movb	%ah,%al
400	NOP
401	outb	%al,$ IO_ICU2+1
402	NOP
403	movzwl	_cpl,%eax		# return old priority
404	movw	%dx,_cpl		# set new priority level
405	sti				# enable interrupts
406	ret
407
408	.globl	_iml15			# mask off all but irq0-1,8-14
409_iml15:
410	cli				# disable interrupts
411	movw	$0x80f8,%ax		# set new priority level
412	movw	%ax,%dx
413	orw	_imen,%ax		# mask off those not enabled yet
414	movw	%ax,%cx
415	NOP
416	outb	%al,$ IO_ICU1+1		/* update icu's */
417	NOP
418	movb	%ah,%al
419	NOP
420	outb	%al,$ IO_ICU2+1
421	NOP
422	movzwl	_cpl,%eax		# return old priority
423	movw	%dx,_cpl		# set new priority level
424	sti				# enable interrupts
425	ret
426
427	.globl	_iml3			# mask off all but irq0-1,8-15
428_iml3:
429	cli				# disable interrupts
430	movw	$0x00f8,%ax		# set new priority level
431	movw	%ax,%dx
432	orw	_imen,%ax		# mask off those not enabled yet
433	movw	%ax,%cx
434	NOP
435	outb	%al,$ IO_ICU1+1		/* update icu's */
436	NOP
437	movb	%ah,%al
438	NOP
439	outb	%al,$ IO_ICU2+1
440	NOP
441	movzwl	_cpl,%eax		# return old priority
442	movw	%dx,_cpl		# set new priority level
443	sti				# enable interrupts
444	ret
445
446	.globl	_iml4			# mask off all but irq0-1,8-15,3
447_iml4:
448	cli				# disable interrupts
449	movw	$0x00f0,%ax		# set new priority level
450	movw	%ax,%dx
451	orw	_imen,%ax		# mask off those not enabled yet
452	movw	%ax,%cx
453	NOP
454	outb	%al,$ IO_ICU1+1		/* update icu's */
455	NOP
456	movb	%ah,%al
457	NOP
458	outb	%al,$ IO_ICU2+1
459	NOP
460	movzwl	_cpl,%eax		# return old priority
461	movw	%dx,_cpl		# set new priority level
462	sti				# enable interrupts
463	ret
464
465	.globl	_iml5			# mask off all but irq0-1,8-15,3-4
466_iml5:
467	cli				# disable interrupts
468	movw	$0x00e0,%ax		# set new priority level
469	movw	%ax,%dx
470	orw	_imen,%ax		# mask off those not enabled yet
471	movw	%ax,%cx
472	NOP
473	outb	%al,$ IO_ICU1+1		/* update icu's */
474	NOP
475	movb	%ah,%al
476	NOP
477	outb	%al,$ IO_ICU2+1
478	NOP
479	movzwl	_cpl,%eax		# return old priority
480	movw	%dx,_cpl		# set new priority level
481	sti				# enable interrupts
482	ret
483
484	.globl	_iml6			# mask off all but irq0-1,8-15,3-5
485_iml6:
486	cli				# disable interrupts
487	movw	$0x00c0,%ax		# set new priority level
488	movw	%ax,%dx
489	orw	_imen,%ax		# mask off those not enabled yet
490	movw	%ax,%cx
491	NOP
492	outb	%al,$ IO_ICU1+1		/* update icu's */
493	NOP
494	movb	%ah,%al
495	NOP
496	outb	%al,$ IO_ICU2+1
497	NOP
498	movzwl	_cpl,%eax		# return old priority
499	movw	%dx,_cpl		# set new priority level
500	sti				# enable interrupts
501	ret
502
503#endif	notyet
504
505	/* hardware interrupt catcher (IDT 32 - 47) */
506	.globl	_isa_strayintr
507
508IDTVEC(intr0)
509	INTR(0) ; call	_isa_strayintr ; INTREXT1
510
511IDTVEC(intr1)
512	INTR(1) ; call	_isa_strayintr ; INTREXT1
513
514IDTVEC(intr2)
515	INTR(2) ; call	_isa_strayintr ; INTREXT1
516
517IDTVEC(intr3)
518	INTR(3) ; call	_isa_strayintr ; INTREXT1
519
520IDTVEC(intr4)
521	INTR(4) ; call	_isa_strayintr ; INTREXT1
522
523IDTVEC(intr5)
524	INTR(5) ; call	_isa_strayintr ; INTREXT1
525
526IDTVEC(intr6)
527	INTR(6) ; call	_isa_strayintr ; INTREXT1
528
529IDTVEC(intr7)
530	INTR(7) ; call	_isa_strayintr ; INTREXT1
531
532
533IDTVEC(intr8)
534	INTR(8) ; call	_isa_strayintr ; INTREXT2
535
536IDTVEC(intr9)
537	INTR(9) ; call	_isa_strayintr ; INTREXT2
538
539IDTVEC(intr10)
540	INTR(10) ; call	_isa_strayintr ; INTREXT2
541
542IDTVEC(intr11)
543	INTR(11) ; call	_isa_strayintr ; INTREXT2
544
545IDTVEC(intr12)
546	INTR(12) ; call	_isa_strayintr ; INTREXT2
547
548IDTVEC(intr13)
549	INTR(13) ; call	_isa_strayintr ; INTREXT2
550
551IDTVEC(intr14)
552	INTR(14) ; call	_isa_strayintr ; INTREXT2
553
554IDTVEC(intr15)
555	INTR(15) ; call	_isa_strayintr ; INTREXT2
556
557