xref: /original-bsd/sys/i386/isa/icu.s (revision 9842e909)
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.3 (Berkeley) 09/03/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	DONET(NETISR_ARP,_arpintr)
94#endif
95#ifdef IMP
96	DONET(NETISR_IMP,_impintr)
97#endif
98#ifdef NS
99	DONET(NETISR_NS,_nsintr)
100#endif
101#ifdef ISO
102	DONET(NETISR_ISO,_clnlintr)
103#endif
104#ifdef CCITT
105	DONET(NETISR_CCITT,_hdintr)
106#endif
107
108	popl	%eax
109	movw	%ax,_cpl
110	orw	_imen,%ax
111	NOP
112	outb	%al,$ IO_ICU1+1		# re-enable intr?
113	NOP
114	movb	%ah,%al
115	NOP
116	outb	%al,$ IO_ICU2+1
117	NOP
118	inb	$0x84,%al
119
120	# btrl	$ NETISR_SCLK,_netisr
121	movl	$ NETISR_SCLK,%eax	# stupid assembler, as usual
122	btrl	%eax,_netisr
123	jnb	1f
124	# back to an interrupt frame for a moment
125	call	_splsoftclock
126	pushl	%eax
127	pushl	$0xff	# dummy intr
128	call	_softclock
129	popl	%eax
130	call	_splx
131	popl	%eax
132
133	jmp	2f
134
135	/* 1:	btrl	$NETISR_AST,_netisr*/
1361:
137	cmpw	$0x1f,13*4(%esp)	# to user?
138	jne	2f			# nope, leave
139	movl	$ NETISR_AST,%eax	# stupid assembler, as usual
140	btrl	%eax,_netisr
141	jnb	2f
142	call	_trap
143
1442:	pop	%es
145	pop	%ds
146	popal
147	addl	$8,%esp
148	iret
149
150/*
151 * Interrupt priority mechanism
152 *
153 * Two flavors	-- imlXX masks relative to ISA noemenclature (for PC compat sw)
154 *		-- splXX masks with group mechanism for BSD purposes
155 */
156
157	.globl	_splhigh
158	.globl	_splclock
159_splhigh:
160_splclock:
161	cli				# disable interrupts
162	movw	$0xffff,%ax		# set new priority level
163	movw	%ax,%dx
164	# orw	_imen,%ax		# mask off those not enabled yet
165	movw	%ax,%cx
166	NOP
167	outb	%al,$ IO_ICU1+1		/* update icu's */
168	NOP
169	movb	%ah,%al
170	NOP
171	outb	%al,$ IO_ICU2+1
172	NOP
173	inb	$0x84,%al
174	movzwl	_cpl,%eax		# return old priority
175	movw	%dx,_cpl		# set new priority level
176	sti				# enable interrupts
177	ret
178
179	.globl	_spltty			# block clists
180_spltty:
181	cli				# disable interrupts
182	movw	_cpl,%ax
183	orw	_ttymask,%ax
184	movw	%ax,%dx
185	orw	_imen,%ax		# mask off those not enabled yet
186	movw	%ax,%cx
187	NOP
188	outb	%al,$ IO_ICU1+1		/* update icu's */
189	NOP
190	movb	%ah,%al
191	NOP
192	outb	%al,$ IO_ICU2+1
193	NOP
194	inb	$0x84,%al
195	movzwl	_cpl,%eax		# return old priority
196	movw	%dx,_cpl		# set new priority level
197	sti				# enable interrupts
198	ret
199
200	.globl	_splimp
201	.globl	_splnet
202_splimp:
203_splnet:
204	cli				# disable interrupts
205	movw	_cpl,%ax
206	orw	_netmask,%ax
207	movw	%ax,%dx
208	orw	_imen,%ax		# mask off those not enabled yet
209	movw	%ax,%cx
210	NOP
211	outb	%al,$ IO_ICU1+1		/* update icu's */
212	NOP
213	movb	%ah,%al
214	NOP
215	outb	%al,$ IO_ICU2+1
216	NOP
217	inb	$0x84,%al
218	movzwl	_cpl,%eax		# return old priority
219	movw	%dx,_cpl		# set new priority level
220	sti				# enable interrupts
221	ret
222
223	.globl	_splbio
224_splbio:
225	cli				# disable interrupts
226	movw	_cpl,%ax
227	orw	_biomask,%ax
228	movw	%ax,%dx
229	orw	_imen,%ax		# mask off those not enabled yet
230	movw	%ax,%cx
231	NOP
232	outb	%al,$ IO_ICU1+1		/* update icu's */
233	NOP
234	movb	%ah,%al
235	NOP
236	outb	%al,$ IO_ICU2+1
237	NOP
238	inb	$0x84,%al
239	movzwl	_cpl,%eax		# return old priority
240	movw	%dx,_cpl		# set new priority level
241	sti				# enable interrupts
242	ret
243
244	.globl	_splsoftclock
245_splsoftclock:
246	cli				# disable interrupts
247	movw	_cpl,%ax
248	orw	$0x8000,%ax		# set new priority level
249	movw	%ax,%dx
250	orw	_imen,%ax		# mask off those not enabled yet
251	movw	%ax,%cx
252	NOP
253	outb	%al,$ IO_ICU1+1		/* update icu's */
254	NOP
255	movb	%ah,%al
256	NOP
257	outb	%al,$ IO_ICU2+1
258	NOP
259	inb	$0x84,%al
260	movzwl	_cpl,%eax		# return old priority
261	movw	%dx,_cpl		# set new priority level
262	sti				# enable interrupts
263	ret
264
265	.globl _splnone
266	.globl _spl0
267_splnone:
268_spl0:
269	cli				# disable interrupts
270	pushl	_cpl			# save old priority
271	movw	_cpl,%ax
272	orw	_netmask,%ax		# mask off those network devices
273	movw	%ax,_cpl		# set new priority level
274	orw	_imen,%ax		# mask off those not enabled yet
275	NOP
276	outb	%al,$ IO_ICU1+1		/* update icu's */
277	NOP
278	movb	%ah,%al
279	NOP
280	outb	%al,$ IO_ICU2+1
281	NOP
282	inb	$0x84,%al
283	sti				# enable interrupts
284
285	DONET(NETISR_RAW,_rawintr)
286#ifdef INET
287	DONET(NETISR_IP,_ipintr)
288#endif
289	cli				# disable interrupts
290	popl	_cpl			# save old priority
291	movw	$0,%ax			# set new priority level
292	movw	%ax,%dx
293	orw	_imen,%ax		# mask off those not enabled yet
294	movw	%ax,%cx
295	NOP
296	outb	%al,$ IO_ICU1+1		/* update icu's */
297	NOP
298	movb	%ah,%al
299	NOP
300	outb	%al,$ IO_ICU2+1
301	NOP
302	inb	$0x84,%al
303	movzwl	_cpl,%eax		# return old priority
304	movw	%dx,_cpl		# set new priority level
305	sti				# enable interrupts
306	ret
307
308	.globl _splx
309_splx:
310	cli				# disable interrupts
311	movw	4(%esp),%ax		# new priority level
312	movw	%ax,%dx
313	cmpw	$0,%dx
314	je	_spl0			# going to "zero level" is special
315
316	orw	_imen,%ax		# mask off those not enabled yet
317	movw	%ax,%cx
318	NOP
319	outb	%al,$ IO_ICU1+1		/* update icu's */
320	NOP
321	movb	%ah,%al
322	NOP
323	outb	%al,$ IO_ICU2+1
324	NOP
325	inb	$0x84,%al
326	movzwl	_cpl,%eax		# return old priority
327	movw	%dx,_cpl		# set new priority level
328	sti				# enable interrupts
329	ret
330
331#ifdef notyet
332	.globl	_iml8			# mask off all but irq0-1
333_iml8:
334	cli				# disable interrupts
335	movw	$0xfffc,%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	_iml10			# mask off all but irq0-1,8-9
352_iml10:
353	cli				# disable interrupts
354	movw	$0xfcf8,%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	_iml11			# mask off all but irq0-1,8-10
371_iml11:
372	cli				# disable interrupts
373	movw	$0xf8f8,%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	_iml12			# mask off all but irq0-1,8-11
390_iml12:
391	cli				# disable interrupts
392	movw	$0xf0f8,%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	_iml13			# mask off all but irq0-1,8-12
409_iml13:
410	cli				# disable interrupts
411	movw	$0xe0f8,%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	_iml15			# mask off all but irq0-1,8-14
428_iml15:
429	cli				# disable interrupts
430	movw	$0x80f8,%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	_iml3			# mask off all but irq0-1,8-15
447_iml3:
448	cli				# disable interrupts
449	movw	$0x00f8,%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	_iml4			# mask off all but irq0-1,8-15,3
466_iml4:
467	cli				# disable interrupts
468	movw	$0x00f0,%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	_iml5			# mask off all but irq0-1,8-15,3-4
485_iml5:
486	cli				# disable interrupts
487	movw	$0x00e0,%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	.globl	_iml6			# mask off all but irq0-1,8-15,3-5
504_iml6:
505	cli				# disable interrupts
506	movw	$0x00c0,%ax		# set new priority level
507	movw	%ax,%dx
508	orw	_imen,%ax		# mask off those not enabled yet
509	movw	%ax,%cx
510	NOP
511	outb	%al,$ IO_ICU1+1		/* update icu's */
512	NOP
513	movb	%ah,%al
514	NOP
515	outb	%al,$ IO_ICU2+1
516	NOP
517	movzwl	_cpl,%eax		# return old priority
518	movw	%dx,_cpl		# set new priority level
519	sti				# enable interrupts
520	ret
521
522#endif	notyet
523
524	/* hardware interrupt catcher (IDT 32 - 47) */
525	.globl	_isa_strayintr
526
527IDTVEC(intr0)
528	INTR(0, _highmask, 0) ; call	_isa_strayintr ; INTREXIT1
529
530IDTVEC(intr1)
531	INTR(1, _highmask, 1) ; call	_isa_strayintr ; INTREXIT1
532
533IDTVEC(intr2)
534	INTR(2, _highmask, 2) ; call	_isa_strayintr ; INTREXIT1
535
536IDTVEC(intr3)
537	INTR(3, _highmask, 3) ; call	_isa_strayintr ; INTREXIT1
538
539IDTVEC(intr4)
540	INTR(4, _highmask, 4) ; call	_isa_strayintr ; INTREXIT1
541
542IDTVEC(intr5)
543	INTR(5, _highmask, 5) ; call	_isa_strayintr ; INTREXIT1
544
545IDTVEC(intr6)
546	INTR(6, _highmask, 6) ; call	_isa_strayintr ; INTREXIT1
547
548IDTVEC(intr7)
549	INTR(7, _highmask, 7) ; call	_isa_strayintr ; INTREXIT1
550
551
552IDTVEC(intr8)
553	INTR(8, _highmask, 8) ; call	_isa_strayintr ; INTREXIT2
554
555IDTVEC(intr9)
556	INTR(9, _highmask, 9) ; call	_isa_strayintr ; INTREXIT2
557
558IDTVEC(intr10)
559	INTR(10, _highmask, 10) ; call	_isa_strayintr ; INTREXIT2
560
561IDTVEC(intr11)
562	INTR(11, _highmask, 11) ; call	_isa_strayintr ; INTREXIT2
563
564IDTVEC(intr12)
565	INTR(12, _highmask, 12) ; call	_isa_strayintr ; INTREXIT2
566
567IDTVEC(intr13)
568	INTR(13, _highmask, 13) ; call	_isa_strayintr ; INTREXIT2
569
570IDTVEC(intr14)
571	INTR(14, _highmask, 14) ; call	_isa_strayintr ; INTREXIT2
572
573IDTVEC(intr15)
574	INTR(15, _highmask, 15) ; call	_isa_strayintr ; INTREXIT2
575
576