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