Subject: generic soft interrupt patch
To: None <port-arc@netbsd.org>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: port-arc
Date: 04/28/2003 15:35:17
I've just made a patch to support generic soft interrupt for arc.
It's based on algor port (as newsmips patch) and seems to work
on my NEC-JC94, but I'm not sure if isabus.c fix is correct or not.
(Has anyone tried any ISA device that uses interrupts on arc?)

Note it seems that getty for /dev/tty00 does not work if console isn't
com, but I think old kernels also has the same problem.

cpu_intr() in arc_trap.c should also be rewritten as noted
in arch/arc/TODO file, but it's a future work.
(BTW, we should rename arc_trap.c to interrupt.c like other mips ports?)
---
Izumi Tsutsui
tsutsui@ceres.dti.ne.jp

Index: arc/arc_trap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/arc/arc_trap.c,v
retrieving revision 1.24
diff -u -r1.24 arc_trap.c
--- arc/arc_trap.c	2003/04/27 17:13:01	1.24
+++ arc/arc_trap.c	2003/04/28 06:03:51
@@ -2,6 +2,42 @@
 /*	$OpenBSD: trap.c,v 1.22 1999/05/24 23:08:59 jason Exp $	*/
 
 /*
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
  * Copyright (c) 1988 University of Utah.
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -46,9 +82,12 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
+#include <sys/malloc.h>
 
 #include <uvm/uvm_extern.h>
 
+#include <net/netisr.h>			/* Legacy softnet support */
+
 #include <mips/locore.h>
 
 #include <machine/autoconf.h>
@@ -60,6 +99,20 @@
 
 int arc_hardware_intr __P((u_int32_t, u_int32_t, u_int32_t, u_int32_t));
 
+/* XXX For legacy software interrupts. */
+struct arc_soft_intrhand *softnet_intrhand;
+
+const u_int32_t *ipl_sr_bits;
+
+const u_int32_t ipl_si_to_sr[_IPL_NSOFT] = {
+	MIPS_SOFT_INT_MASK_0,			/* IPL_SOFT */
+	MIPS_SOFT_INT_MASK_0,			/* IPL_SOFTCLOCK */
+	MIPS_SOFT_INT_MASK_1,			/* IPL_SOFTNET */
+	MIPS_SOFT_INT_MASK_1,			/* IPL_SOFTSERIAL */
+};
+
+struct arc_soft_intr arc_soft_intrs[_IPL_NSOFT];
+
 #define	MIPS_INT_LEVELS	8
 
 struct {
@@ -133,46 +186,131 @@
 	u_int32_t pc;
 	u_int32_t ipending;		/* pending interrupts & enable mask */
 {
-#if defined(MIPS3) && defined(MIPS_INT_MASK_CLOCK)
-	if ((ipending & MIPS_INT_MASK_CLOCK) && CPUISMIPS3) {
+	struct arc_soft_intr *asi;
+	struct arc_soft_intrhand *sih;
+	int i, s;
+
+	if (ipending & MIPS_INT_MASK_CLOCK) {
 		/*
 		 *  Writing a value to the Compare register,
 		 *  as a side effect, clears the timer interrupt request.
 		 */
 		mips3_cp0_compare_write(mips3_cp0_count_read());
 	}
-#endif
 
 	uvmexp.intrs++;
 	/* real device interrupt */
 	if (ipending & INT_MASK_REAL_DEV) {
 		_splset(arc_hardware_intr(status, cause, pc, ipending));
 	}
+
+	/* software interrupts */
+	ipending &= (MIPS_SOFT_INT_MASK_1|MIPS_SOFT_INT_MASK_0);
+	if (ipending == 0)
+		return;
+
+	_clrsoftintr(ipending);
 
-#if defined(MIPS1) && defined(INT_MASK_FPU)
-	if ((ipending & INT_MASK_FPU) && CPUISMIPS1) {
-		intrcnt[FPU_INTR]++;
-		if (!USERMODE(status))
-			panic("kernel used FPU: PC %x, CR %x, SR %x",
-			    pc, cause, status);
-#if !defined(SOFTFLOAT)
-		MachFPInterrupt(status, cause, pc, curlwp->l_md.md_regs);
-#endif
-	}
-#endif
-
-	/* 'softnet' interrupt */
-	if (ipending & MIPS_SOFT_INT_MASK_1) {
-		clearsoftnet();
-		uvmexp.softs++;
-		netintr();
-	}
-
-	/* 'softclock' interrupt */
-	if (ipending & MIPS_SOFT_INT_MASK_0) {
-		clearsoftclock();
-		uvmexp.softs++;
-		intrcnt[SOFTCLOCK_INTR]++;
-		softclock(NULL);
+	for (i = _IPL_NSOFT - 1; i >= 0; i--) {
+		if ((ipending & ipl_si_to_sr[i]) == 0)
+			continue;
+
+		asi = &arc_soft_intrs[i];
+
+		if (TAILQ_FIRST(&asi->softintr_q) != NULL)
+			asi->softintr_evcnt.ev_count++;
+
+		for (;;) {
+			s = splhigh();
+
+			sih = TAILQ_FIRST(&asi->softintr_q);
+			if (sih != NULL) {
+				TAILQ_REMOVE(&asi->softintr_q, sih, sih_q);
+				sih->sih_pending = 0;
+			}
+
+			splx(s);
+
+			if (sih == NULL)
+				break;
+
+			uvmexp.softs++;
+			(*sih->sih_func)(sih->sih_arg);
+		}
 	}
+}
+
+/*
+ * softintr_init:
+ *
+ *	Initialize the software interrupt system.
+ */
+void
+softintr_init(void)
+{
+	static const char *softintr_names[] = IPL_SOFTNAMES;
+	struct arc_soft_intr *asi;
+	int i;
+
+	for (i = 0; i < _IPL_NSOFT; i++) {
+		asi = &arc_soft_intrs[i];
+		TAILQ_INIT(&asi->softintr_q);
+		asi->softintr_ipl = IPL_SOFT + i;
+		evcnt_attach_dynamic(&asi->softintr_evcnt, EVCNT_TYPE_INTR,
+		    NULL, "soft", softintr_names[i]);
+	}
+
+	/* XXX Establish legacy soft interrupt handlers. */
+	softnet_intrhand = softintr_establish(IPL_SOFTNET,
+	    (void (*)(void *))netintr, NULL);
+
+	KASSERT(softnet_intrhand != NULL);
+}
+
+/*
+ * softintr_establish:		[interface]
+ *
+ *	Register a software interrupt handler.
+ */
+void *
+softintr_establish(int ipl, void (*func)(void *), void *arg)
+{
+	struct arc_soft_intr *asi;
+	struct arc_soft_intrhand *sih;
+
+	if (__predict_false(ipl >= (IPL_SOFT + _IPL_NSOFT) || ipl < IPL_SOFT))
+		panic("softintr_establish");
+
+	asi = &arc_soft_intrs[ipl - IPL_SOFT];
+
+	sih = malloc(sizeof(*sih), M_DEVBUF, M_NOWAIT);
+	if (__predict_true(sih != NULL)) {
+		sih->sih_intrhead = asi;
+		sih->sih_func = func;
+		sih->sih_arg = arg;
+		sih->sih_pending = 0;
+	}
+	return sih;
+}
+
+/*
+ * softintr_disestablish:	[interface]
+ *
+ *	Unregister a software interrupt handler.
+ */
+void
+softintr_disestablish(void *arg)
+{
+	struct arc_soft_intrhand *sih = arg;
+	struct arc_soft_intr *asi = sih->sih_intrhead;
+	int s;
+
+	s = splhigh();
+	if (sih->sih_pending) {
+		TAILQ_REMOVE(&asi->softintr_q, sih, sih_q);
+		sih->sih_pending = 0;
+	}
+	splx(s);
+
+	free(sih, M_DEVBUF);
 }
Index: arc/autoconf.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/arc/autoconf.c,v
retrieving revision 1.18
diff -u -r1.18 autoconf.c
--- arc/autoconf.c	2002/09/27 02:24:09	1.18
+++ arc/autoconf.c	2003/04/28 06:03:51
@@ -91,6 +91,9 @@
 void
 cpu_configure()
 {
+
+	softintr_init();
+
 	(void)splhigh();	/* To be really sure.. */
 	if (config_rootfound("mainbus", "mainbus") == NULL)
 		panic("no mainbus found");
Index: arc/c_magnum.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/arc/c_magnum.c,v
retrieving revision 1.3
diff -u -r1.3 c_magnum.c
--- arc/c_magnum.c	2003/04/27 11:33:36	1.3
+++ arc/c_magnum.c	2003/04/28 06:03:52
@@ -80,6 +80,54 @@
 	timer_magnum_init,
 };
 
+/*
+ * This is a mask of bits to clear in the SR when we go to a
+ * given interrupt priority level.
+ */
+static const u_int32_t magnum_ipl_sr_bits[_IPL_N] = {
+	0,					/* IPL_NONE */
+
+	MIPS_SOFT_INT_MASK_0,			/* IPL_SOFT */
+
+	MIPS_SOFT_INT_MASK_0,			/* IPL_SOFTCLOCK */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1,		/* IPL_SOFTNET */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1,		/* IPL_SOFTSERIAL */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1|
+		MIPS_INT_MASK_0|
+		MIPS_INT_MASK_1|
+		MIPS_INT_MASK_2|
+		MIPS_INT_MASK_3,		/* IPL_BIO */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1|
+		MIPS_INT_MASK_0|
+		MIPS_INT_MASK_1|
+		MIPS_INT_MASK_2|
+		MIPS_INT_MASK_3,		/* IPL_NET */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1|
+		MIPS_INT_MASK_0|
+		MIPS_INT_MASK_1|
+		MIPS_INT_MASK_2|
+		MIPS_INT_MASK_3,		/* IPL_{TTY,SERIAL} */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1|
+		MIPS_INT_MASK_0|
+		MIPS_INT_MASK_1|
+		MIPS_INT_MASK_2|
+		MIPS_INT_MASK_3|
+		MIPS_INT_MASK_4|
+		MIPS_INT_MASK_5,		/* IPL_{CLOCK,HIGH} */
+};
+
 int
 timer_magnum_intr(mask, cf)
 	u_int mask;
@@ -189,12 +237,7 @@
 	/*
 	 * Initialize interrupt priority
 	 */
-	splvec.splnet = MIPS_INT_MASK_SPL3;
-	splvec.splbio = MIPS_INT_MASK_SPL3;
-	splvec.splvm = MIPS_INT_MASK_SPL3;
-	splvec.spltty = MIPS_INT_MASK_SPL3;
-	splvec.splclock = MIPS_INT_MASK_SPL5;
-	splvec.splstatclock = MIPS_INT_MASK_SPL5;
+	ipl_sr_bits = magnum_ipl_sr_bits;
 
 	/*
 	 * Disable all interrupts. New masks will be set up
Index: arc/c_nec_eisa.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/arc/c_nec_eisa.c,v
retrieving revision 1.5
diff -u -r1.5 c_nec_eisa.c
--- arc/c_nec_eisa.c	2003/01/31 22:07:52	1.5
+++ arc/c_nec_eisa.c	2003/04/28 06:03:52
@@ -73,6 +73,51 @@
 	isabr_nec_eisa_intr_status,
 };
 
+/*
+ * This is a mask of bits to clear in the SR when we go to a
+ * given interrupt priority level.
+ */
+static const u_int32_t nec_eisa_ipl_sr_bits[_IPL_N] = {
+	0,					/* IPL_NONE */
+
+	MIPS_SOFT_INT_MASK_0,			/* IPL_SOFT */
+
+	MIPS_SOFT_INT_MASK_0,			/* IPL_SOFTCLOCK */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1,		/* IPL_SOFTNET */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1,		/* IPL_SOFTSERIAL */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1|
+		MIPS_INT_MASK_0|
+		MIPS_INT_MASK_1|
+		MIPS_INT_MASK_2,		/* IPL_BIO */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1|
+		MIPS_INT_MASK_0|
+		MIPS_INT_MASK_1|
+		MIPS_INT_MASK_2,		/* IPL_NET */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1|
+		MIPS_INT_MASK_0|
+		MIPS_INT_MASK_1|
+		MIPS_INT_MASK_2,		/* IPL_{TTY,SERIAL} */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1|
+		MIPS_INT_MASK_0|
+		MIPS_INT_MASK_1|
+		MIPS_INT_MASK_2|
+		MIPS_INT_MASK_3|
+		MIPS_INT_MASK_4|
+		MIPS_INT_MASK_5,		/* IPL_{CLOCK,HIGH} */
+};
+
 int
 isabr_nec_eisa_intr_status()
 {
@@ -131,12 +176,7 @@
 	/*
 	 * Initialize interrupt priority
 	 */
-	splvec.splnet = MIPS_INT_MASK_SPL2;
-	splvec.splbio = MIPS_INT_MASK_SPL2;
-	splvec.splvm = MIPS_INT_MASK_SPL2;
-	splvec.spltty = MIPS_INT_MASK_SPL2;
-	splvec.splclock = MIPS_INT_MASK_SPL5;
-	splvec.splstatclock = MIPS_INT_MASK_SPL5;
+	ipl_sr_bits = nec_eisa_ipl_sr_bits;
 
 	/*
 	 * Disable all interrupts. New masks will be set up
Index: arc/c_nec_pci.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/arc/c_nec_pci.c,v
retrieving revision 1.4
diff -u -r1.4 c_nec_pci.c
--- arc/c_nec_pci.c	2003/01/19 10:06:12	1.4
+++ arc/c_nec_pci.c	2003/04/28 06:03:53
@@ -98,6 +98,51 @@
 	{ mc_nec_pci_read, mc_nec_pci_write }
 };
 
+/*
+ * This is a mask of bits to clear in the SR when we go to a
+ * given interrupt priority level.
+ */
+static const u_int32_t nec_pci_ipl_sr_bits[_IPL_N] = {
+	0,					/* IPL_NONE */
+
+	MIPS_SOFT_INT_MASK_0,			/* IPL_SOFT */
+
+	MIPS_SOFT_INT_MASK_0,			/* IPL_SOFTCLOCK */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1,		/* IPL_SOFTNET */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1,		/* IPL_SOFTSERIAL */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1|
+		MIPS_INT_MASK_0|
+		MIPS_INT_MASK_1|
+		MIPS_INT_MASK_2,		/* IPL_BIO */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1|
+		MIPS_INT_MASK_0|
+		MIPS_INT_MASK_1|
+		MIPS_INT_MASK_2,		/* IPL_NET */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1|
+		MIPS_INT_MASK_0|
+		MIPS_INT_MASK_1|
+		MIPS_INT_MASK_2,		/* IPL_{TTY,SERIAL} */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1|
+		MIPS_INT_MASK_0|
+		MIPS_INT_MASK_1|
+		MIPS_INT_MASK_2|
+		MIPS_INT_MASK_3|
+		MIPS_INT_MASK_4|
+		MIPS_INT_MASK_5,		/* IPL_{CLOCK,HIGH} */
+};
+
 u_int
 mc_nec_pci_read(sc, reg)
 	struct mcclock_softc *sc;
@@ -194,12 +239,7 @@
 	/*
 	 * Initialize interrupt priority
 	 */
-	splvec.splnet = MIPS_INT_MASK_SPL2;
-	splvec.splbio = MIPS_INT_MASK_SPL2;
-	splvec.splvm = MIPS_INT_MASK_SPL2;
-	splvec.spltty = MIPS_INT_MASK_SPL2;
-	splvec.splclock = MIPS_INT_MASK_SPL5;
-	splvec.splstatclock = MIPS_INT_MASK_SPL5;
+	ipl_sr_bits = nec_pci_ipl_sr_bits;
 
 	/*
 	 * Disable all interrupts. New masks will be set up
Index: arc/locore_machdep.S
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/arc/locore_machdep.S,v
retrieving revision 1.8
diff -u -r1.8 locore_machdep.S
--- arc/locore_machdep.S	2000/06/09 05:07:32	1.8
+++ arc/locore_machdep.S	2003/04/28 06:03:53
@@ -392,19 +392,14 @@
 
 
 /*
- * Interrupt counters for vmstat.
+ * Symbols that vmstat -i wants, even though they're not used.
  */
 	.data
 	.globl _C_LABEL(intrcnt)
 	.globl _C_LABEL(eintrcnt)
 	.globl _C_LABEL(intrnames)
 	.globl _C_LABEL(eintrnames)
-_C_LABEL(intrnames):
-	.asciiz	"softclock"
-	.asciiz	"softnet"
-	.asciiz	"fpu"
-_C_LABEL(eintrnames):
-	.align	3
 _C_LABEL(intrcnt):
-	.word	0,0,0
 _C_LABEL(eintrcnt):
+_C_LABEL(intrnames):
+_C_LABEL(eintrnames):
Index: arc/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/arc/machdep.c,v
retrieving revision 1.77
diff -u -r1.77 machdep.c
--- arc/machdep.c	2003/04/27 17:05:56	1.77
+++ arc/machdep.c	2003/04/28 06:03:54
@@ -180,15 +180,6 @@
  */
 int	safepri = MIPS3_PSL_LOWIPL;
 
-struct splvec	splvec = {			/* XXX will go XXX */
-	MIPS_INT_MASK_SPLHIGH, /* splbio */
-	MIPS_INT_MASK_SPLHIGH, /* splnet */
-	MIPS_INT_MASK_SPLHIGH, /* spltty */
-	MIPS_INT_MASK_SPLHIGH, /* splvm */
-	MIPS_INT_MASK_SPLHIGH, /* splclock */
-	MIPS_INT_MASK_SPLHIGH, /* splstatclock */
-};
-
 extern char kernel_text[], edata[], end[];
 extern struct user *proc0paddr;
 
Index: arc/p_dti_arcstation.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/arc/p_dti_arcstation.c,v
retrieving revision 1.1
diff -u -r1.1 p_dti_arcstation.c
--- arc/p_dti_arcstation.c	2001/06/13 15:27:17	1.1
+++ arc/p_dti_arcstation.c	2003/04/28 06:03:54
@@ -95,6 +95,61 @@
 	arc_set_intr,
 };
 
+/*
+ * This is a mask of bits to clear in the SR when we go to a
+ * given interrupt priority level.
+ */
+/* XXX see comments in p_dti_arcstation_init() */
+static const u_int32_t dti_arcstation_ipl_sr_bits[_IPL_N] = {
+	0,					/* IPL_NONE */
+
+	MIPS_SOFT_INT_MASK_0,			/* IPL_SOFT */
+
+	MIPS_SOFT_INT_MASK_0,			/* IPL_SOFTCLOCK */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1,		/* IPL_SOFTNET */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1,		/* IPL_SOFTSERIAL */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1|
+		MIPS_INT_MASK_0|
+		MIPS_INT_MASK_1|
+		MIPS_INT_MASK_2|
+		MIPS_INT_MASK_3|
+		MIPS_INT_MASK_4|
+		MIPS_INT_MASK_5,		/* XXX IPL_BIO */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1|
+		MIPS_INT_MASK_0|
+		MIPS_INT_MASK_1|
+		MIPS_INT_MASK_2|
+		MIPS_INT_MASK_3|
+		MIPS_INT_MASK_4|
+		MIPS_INT_MASK_5,		/* XXX IPL_NET */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1|
+		MIPS_INT_MASK_0|
+		MIPS_INT_MASK_1|
+		MIPS_INT_MASK_2|
+		MIPS_INT_MASK_3|
+		MIPS_INT_MASK_4|
+		MIPS_INT_MASK_5,		/* XXX IPL_{TTY,SERIAL} */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1|
+		MIPS_INT_MASK_0|
+		MIPS_INT_MASK_1|
+		MIPS_INT_MASK_2|
+		MIPS_INT_MASK_3|
+		MIPS_INT_MASK_4|
+		MIPS_INT_MASK_5,		/* XXX IPL_{CLOCK,HIGH} */
+};
+
 #if NPC_ISA > 0 || NOPMS_ISA > 0
 /*
  * platform-dependent pccons configuration
@@ -202,6 +257,7 @@
 	 * or
 	 *	- use MIP3_INTERNAL_TIMER_INTERRUPT for clock
 	 */
+	ipl_sr_bits = dti_arcstation_ipl_sr_bits;
 
 	/*
 	 * common configuration for DTI platforms
Index: arc/p_dti_tyne.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/arc/p_dti_tyne.c,v
retrieving revision 1.1
diff -u -r1.1 p_dti_tyne.c
--- arc/p_dti_tyne.c	2001/06/13 15:27:18	1.1
+++ arc/p_dti_tyne.c	2003/04/28 06:03:54
@@ -97,6 +97,61 @@
 	arc_set_intr,
 };
 
+/*
+ * This is a mask of bits to clear in the SR when we go to a
+ * given interrupt priority level.
+ */
+/* XXX see comments in p_dti_tyne_init() */
+static const u_int32_t dti_tyne_ipl_sr_bits[_IPL_N] = {
+	0,					/* IPL_NONE */
+
+	MIPS_SOFT_INT_MASK_0,			/* IPL_SOFT */
+
+	MIPS_SOFT_INT_MASK_0,			/* IPL_SOFTCLOCK */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1,		/* IPL_SOFTNET */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1,		/* IPL_SOFTSERIAL */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1|
+		MIPS_INT_MASK_0|
+		MIPS_INT_MASK_1|
+		MIPS_INT_MASK_2|
+		MIPS_INT_MASK_3|
+		MIPS_INT_MASK_4|
+		MIPS_INT_MASK_5,		/* XXX IPL_BIO */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1|
+		MIPS_INT_MASK_0|
+		MIPS_INT_MASK_1|
+		MIPS_INT_MASK_2|
+		MIPS_INT_MASK_3|
+		MIPS_INT_MASK_4|
+		MIPS_INT_MASK_5,		/* XXX IPL_NET */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1|
+		MIPS_INT_MASK_0|
+		MIPS_INT_MASK_1|
+		MIPS_INT_MASK_2|
+		MIPS_INT_MASK_3|
+		MIPS_INT_MASK_4|
+		MIPS_INT_MASK_5,		/* XXX IPL_{TTY,SERIAL} */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1|
+		MIPS_INT_MASK_0|
+		MIPS_INT_MASK_1|
+		MIPS_INT_MASK_2|
+		MIPS_INT_MASK_3|
+		MIPS_INT_MASK_4|
+		MIPS_INT_MASK_5,		/* XXX IPL_{CLOCK,HIGH} */
+};
+
 #if NPC_ISA > 0 || NOPMS_ISA > 0
 /*
  * platform-dependent pccons configuration
@@ -199,6 +254,7 @@
 	 * or
 	 *	- use MIP3_INTERNAL_TIMER_INTERRUPT for clock
 	 */
+	ipl_sr_bits = dti_tyne_ipl_sr_bits;
 
 	/*
 	 * common configuration for DTI platforms
Index: arc/p_sni_rm200pci.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/arc/p_sni_rm200pci.c,v
retrieving revision 1.1
diff -u -r1.1 p_sni_rm200pci.c
--- arc/p_sni_rm200pci.c	2001/06/13 15:36:44	1.1
+++ arc/p_sni_rm200pci.c	2003/04/28 06:03:55
@@ -79,6 +79,61 @@
 };
 
 /*
+ * This is a mask of bits to clear in the SR when we go to a
+ * given interrupt priority level.
+ */
+/* XXX lack of hardware info for sni_rm200pci */
+static const u_int32_t sni_rm200pci_ipl_sr_bits[_IPL_N] = {
+	0,					/* IPL_NONE */
+
+	MIPS_SOFT_INT_MASK_0,			/* IPL_SOFT */
+
+	MIPS_SOFT_INT_MASK_0,			/* IPL_SOFTCLOCK */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1,		/* IPL_SOFTNET */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1,		/* IPL_SOFTSERIAL */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1|
+		MIPS_INT_MASK_0|
+		MIPS_INT_MASK_1|
+		MIPS_INT_MASK_2|
+		MIPS_INT_MASK_3|
+		MIPS_INT_MASK_4|
+		MIPS_INT_MASK_5,		/* XXX IPL_BIO */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1|
+		MIPS_INT_MASK_0|
+		MIPS_INT_MASK_1|
+		MIPS_INT_MASK_2|
+		MIPS_INT_MASK_3|
+		MIPS_INT_MASK_4|
+		MIPS_INT_MASK_5,		/* XXX IPL_NET */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1|
+		MIPS_INT_MASK_0|
+		MIPS_INT_MASK_1|
+		MIPS_INT_MASK_2|
+		MIPS_INT_MASK_3|
+		MIPS_INT_MASK_4|
+		MIPS_INT_MASK_5,		/* XXX IPL_{TTY,SERIAL} */
+
+	MIPS_SOFT_INT_MASK_0|
+		MIPS_SOFT_INT_MASK_1|
+		MIPS_INT_MASK_0|
+		MIPS_INT_MASK_1|
+		MIPS_INT_MASK_2|
+		MIPS_INT_MASK_3|
+		MIPS_INT_MASK_4|
+		MIPS_INT_MASK_5,		/* XXX IPL_{CLOCK,HIGH} */
+};
+
+/*
  * critial i/o space, interrupt, and other chipset related initialization.
  */
 void
@@ -109,6 +164,7 @@
 	/*
 	 * Initialize interrupt priority
 	 */
+	ipl_sr_bits = sni_rm200pci_ipl_sr_bits;
 }
 
 void
Index: conf/std.arc
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/conf/std.arc,v
retrieving revision 1.14
diff -u -r1.14 std.arc
--- conf/std.arc	2003/04/28 05:03:44	1.14
+++ conf/std.arc	2003/04/28 06:03:55
@@ -18,6 +18,4 @@
 
 options 	MIPS3_L2CACHE_ABSENT	# may not have L2 cache
 
-options 	__NO_SOFT_SERIAL_INTERRUPT	# for "com" driver
-
 makeoptions	DEFTEXTADDR="0x80200000"
Index: include/intr.h
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/include/intr.h,v
retrieving revision 1.10
diff -u -r1.10 intr.h
--- include/intr.h	2001/06/13 15:08:06	1.10
+++ include/intr.h	2003/04/28 06:03:55
@@ -1,7 +1,11 @@
 /*	$NetBSD: intr.h,v 1.10 2001/06/13 15:08:06 soda Exp $	*/
 
-/*
- * Copyright (c) 1998 Jonathan Stone.  All rights reserved.
+/*-
+ * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -13,125 +17,158 @@
  *    documentation and/or other materials provided with the distribution.
  * 3. All advertising materials mentioning features or use of this software
  *    must display the following acknowledgement:
- *	This product includes software developed by Jonathan Stone for
- *      the NetBSD Project.
- * 4. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
+ *	This product includes software developed by the NetBSD
+ *	Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef _ARC_INTR_H_
 #define _ARC_INTR_H_
 
 #define IPL_NONE	0	/* disable only this interrupt */
-#define IPL_BIO		1	/* disable block I/O interrupts */
-#define IPL_NET		2	/* disable network interrupts */
-#define IPL_TTY		3	/* disable terminal interrupts */
-#define IPL_IMP		4	/* memory allocation */
-#define IPL_CLOCK	5	/* disable clock interrupts */
-#define IPL_STATCLOCK	6	/* disable profiling interrupts */
-#if 0 /* XXX */
+
+#define IPL_SOFT	1	/* generic software interrupts (SI 0) */
+#define IPL_SOFTCLOCK	2	/* clock software interrupts (SI 0) */
+#define IPL_SOFTNET	3	/* network software interrupts (SI 1) */
+#define IPL_SOFTSERIAL	4	/* serial software interrupts (SI 1) */
+
+#define IPL_BIO		5	/* disable block I/O interrupts */
+#define IPL_NET		6	/* disable network interrupts */
+#define IPL_TTY		7	/* disable terminal interrupts */
 #define IPL_SERIAL	7	/* disable serial hardware interrupts */
-#endif
+#define IPL_CLOCK	8	/* disable clock interrupts */
+#define IPL_STATCLOCK	8	/* disable profiling interrupts */
 #define IPL_HIGH	8	/* disable all interrupts */
-#define NIPL		9
 
+#define _IPL_NSOFT	4
+#define _IPL_N		9
+
+#define _IPL_SI0_FIRST	IPL_SOFT
+#define _IPL_SI0_LAST	IPL_SOFTCLOCK
+
+#define _IPL_SI1_FIRST	IPL_SOFTNET
+#define _IPL_SI1_LAST	IPL_SOFTSERIAL
+
+#define IPL_SOFTNAMES {							\
+	"misc",								\
+	"clock",							\
+	"net",								\
+	"serial",							\
+}
+
 /* Interrupt sharing types. */
 #define IST_NONE	0	/* none */
 #define IST_PULSE	1	/* pulsed */
 #define IST_EDGE	2	/* edge-triggered */
 #define IST_LEVEL	3	/* level-triggered */
 
-/* Soft interrupt masks. */
-/* XXX - revisit here */
-#define SIR_CLOCK	31
-#define SIR_NET		30
-#define SIR_CLOCKMASK	((1 << SIR_CLOCK))
-#define SIR_NETMASK	((1 << SIR_NET) | SIR_CLOCKMASK)
-#define SIR_ALLMASK	(SIR_CLOCKMASK | SIR_NETMASK)
-
 #ifdef _KERNEL
 #ifndef _LOCORE
 
-#include <mips/cpuregs.h>
+#include <sys/device.h>
+#include <sys/lock.h>
 
-extern int _splraise __P((int));
-extern int _spllower __P((int));
-extern int _splset __P((int));
-extern int _splget __P((void));
-extern void _splnone __P((void));
-extern void _setsoftintr __P((int));
-extern void _clrsoftintr __P((int));
-
-#define setsoftclock()	_setsoftintr(MIPS_SOFT_INT_MASK_0)
-#define setsoftnet()	_setsoftintr(MIPS_SOFT_INT_MASK_1)
-#define clearsoftclock() _clrsoftintr(MIPS_SOFT_INT_MASK_0)
-#define clearsoftnet()	_clrsoftintr(MIPS_SOFT_INT_MASK_1)
+extern const u_int32_t *ipl_sr_bits;
+extern const u_int32_t ipl_si_to_sr[_IPL_NSOFT];
 
-/*
- * nesting interrupt masks.
- */
-#define MIPS_INT_MASK_SPL_SOFT0	MIPS_SOFT_INT_MASK_0
-#define MIPS_INT_MASK_SPL_SOFT1	(MIPS_SOFT_INT_MASK_1|MIPS_INT_MASK_SPL_SOFT0)
-#define MIPS_INT_MASK_SPL0	(MIPS_INT_MASK_0|MIPS_INT_MASK_SPL_SOFT1)
-#define MIPS_INT_MASK_SPL1	(MIPS_INT_MASK_1|MIPS_INT_MASK_SPL0)
-#define MIPS_INT_MASK_SPL2	(MIPS_INT_MASK_2|MIPS_INT_MASK_SPL1)
-#define MIPS_INT_MASK_SPL3	(MIPS_INT_MASK_3|MIPS_INT_MASK_SPL2)
-#define MIPS_INT_MASK_SPL4	(MIPS_INT_MASK_4|MIPS_INT_MASK_SPL3)
-#define MIPS_INT_MASK_SPL5	(MIPS_INT_MASK_5|MIPS_INT_MASK_SPL4)
-#define MIPS_INT_MASK_SPLHIGH	MIPS_INT_MASK_SPL5
+extern int _splraise(int);
+extern int _spllower(int);
+extern int _splset(int);
+extern int _splget(void);
+extern void _splnone(void);
+extern void _setsoftintr(int);
+extern void _clrsoftintr(int);
 
+#define splhigh()	_splraise(ipl_sr_bits[IPL_HIGH])
 #define spl0()		(void)_spllower(0)
 #define splx(s)		(void)_splset(s)
-#define splbio()	(_splraise(splvec.splbio))
-#define splnet()	(_splraise(splvec.splnet))
-#define spltty()	(_splraise(splvec.spltty))
-#define splvm()		(_splraise(splvec.splvm))
-#define splclock()	(_splraise(splvec.splclock))
-#define splstatclock()	(_splraise(splvec.splstatclock))
-#define splhigh()	_splraise(MIPS_INT_MASK_SPLHIGH)
-
-#define splsoftclock()	_splraise(MIPS_INT_MASK_SPL_SOFT0)
-#define splsoftnet()	_splraise(MIPS_INT_MASK_SPL_SOFT1)
-#define spllowersoftclock() _spllower(MIPS_INT_MASK_SPL_SOFT0)
+#define splbio()	_splraise(ipl_sr_bits[IPL_BIO])
+#define splnet()	_splraise(ipl_sr_bits[IPL_NET])
+#define spltty()	_splraise(ipl_sr_bits[IPL_TTY])
+#define splserial()	_splraise(ipl_sr_bits[IPL_SERIAL])
+#define splvm()		spltty()
+#define splclock()	_splraise(ipl_sr_bits[IPL_CLOCK])
+#define splstatclock()	splclock()
 
-#define	splsched()	splhigh()
-#define	spllock()	splhigh()
+#define splsched()	splclock()
+#define spllock()	splhigh()
 #define spllpt()	spltty()		/* lpt driver */
+
+#define splsoft()	_splraise(ipl_sr_bits[IPL_SOFT])
+#define splsoftclock()	_splraise(ipl_sr_bits[IPL_SOFTCLOCK])
+#define splsoftnet()	_splraise(ipl_sr_bits[IPL_SOFTNET])
+#define splsoftserial()	_splraise(ipl_sr_bits[IPL_SOFTSERIAL])
+
+#define spllowersoftclock() _spllower(ipl_sr_bits[IPL_SOFTCLOCK])
+
+#define setsoft(x)							\
+do {									\
+	_setsoftintr(ipl_si_to_sr[(x) - IPL_SOFT]);			\
+} while (/*CONSTCOND*/0)
+
+struct arc_soft_intrhand {
+	TAILQ_ENTRY(arc_soft_intrhand) sih_q;
+	struct arc_soft_intr *sih_intrhead;
+	void (*sih_func)(void *);
+	void *sih_arg;
+	int sih_pending;
+};
 
-struct splvec {
-	int	splbio;
-	int	splnet;
-	int	spltty;
-	int	splvm;
-	int	splclock;
-	int	splstatclock;
+struct arc_soft_intr {
+	TAILQ_HEAD(,arc_soft_intrhand) softintr_q;
+	struct evcnt softintr_evcnt;
+	struct simplelock softintr_slock;
+	unsigned long softintr_ipl;
 };
-extern struct splvec splvec;
 
+void *softintr_establish(int, void (*)(void *), void *);
+void softintr_disestablish(void *);
+void softintr_init(void);
+void softintr_dispatch(void);
+
+#define softintr_schedule(arg)						\
+do {									\
+	struct arc_soft_intrhand *__sih = (arg);			\
+	struct arc_soft_intr *__si = __sih->sih_intrhead;		\
+	int __s;							\
+									\
+	__s = splhigh();						\
+	simple_lock(&__si->softintr_slock);				\
+	if (__sih->sih_pending == 0) {					\
+		TAILQ_INSERT_TAIL(&__si->softintr_q, __sih, sih_q);	\
+		__sih->sih_pending = 1;					\
+		setsoft(__si->softintr_ipl);				\
+	}								\
+	simple_unlock(&__si->softintr_slock);				\
+	splx(__s);							\
+} while (/*CONSTCOND*/0)
+
+/* XXX For legacy software interrupts. */
+extern struct arc_soft_intrhand *softnet_intrhand;
+
+#define setsoftnet()	softintr_schedule(softnet_intrhand)
+
 /*
  * Index into intrcnt[], which is defined in locore
  */
-#define SOFTCLOCK_INTR	0
-#define SOFTNET_INTR	1
-#define FPU_INTR	2
 extern u_long intrcnt[];
 
 struct clockframe;
-void arc_set_intr __P((int, int(*)(u_int, struct clockframe *), int));
-
-/* XXX - revisit here */
-int imask[NIPL];
+void arc_set_intr(int, int(*)(u_int, struct clockframe *), int);
 
 #endif /* !_LOCORE */
 #endif /* _KERNEL */
Index: include/types.h
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/include/types.h,v
retrieving revision 1.13
diff -u -r1.13 types.h
--- include/types.h	2002/03/05 16:12:36	1.13
+++ include/types.h	2003/04/28 06:03:55
@@ -6,6 +6,7 @@
 
 #include <mips/types.h>
 
+#define	__HAVE_GENERIC_SOFT_INTERRUPTS
 #define	__HAVE_DEVICE_REGISTER
 #define	__HAVE_NWSCONS
 
Index: isa/isabus.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/isa/isabus.c,v
retrieving revision 1.19
diff -u -r1.19 isabus.c
--- isa/isabus.c	2003/04/27 17:05:58	1.19
+++ isa/isabus.c	2003/04/28 06:03:55
@@ -133,6 +133,7 @@
 int	fakeintr __P((void *a));
 
 struct isabr_config *isabr_conf = NULL;
+u_int32_t imask[_IPL_N];	/* XXX */
 
 void
 isabrattach(sc)
@@ -217,39 +218,47 @@
 	}
 
 	/* Then figure out which IRQs use each level. */
-	for (level = 0; level < 5; level++) {
+	for (level = 0; level < _IPL_N; level++) {
 		int irqs = 0;
 		for (irq = 0; irq < ICU_LEN; irq++)
 			if (intrlevel[irq] & (1 << level))
 				irqs |= 1 << irq;
-		imask[level] = irqs | SIR_ALLMASK;
+		imask[level] = irqs;
 	}
 
-	/*
-	 * There are tty, network and disk drivers that use free() at interrupt
-	 * time, so imp > (tty | net | bio).
-	 */
-	imask[IPL_IMP] |= imask[IPL_TTY] | imask[IPL_NET] | imask[IPL_BIO];
+	imask[IPL_NONE] = 0;
+
+	imask[IPL_SOFT] |= imask[IPL_NONE];
+	imask[IPL_SOFTCLOCK] |= imask[IPL_SOFT];
+	imask[IPL_SOFTNET] |= imask[IPL_SOFTCLOCK];
+	imask[IPL_SOFTSERIAL] |= imask[IPL_SOFTNET];
 
 	/*
 	 * Enforce a hierarchy that gives slow devices a better chance at not
 	 * dropping data.
 	 */
-	imask[IPL_TTY] |= imask[IPL_NET] | imask[IPL_BIO];
+	imask[IPL_BIO] |= imask[IPL_SOFTSERIAL];
 	imask[IPL_NET] |= imask[IPL_BIO];
+	imask[IPL_TTY] |= imask[IPL_NET];
+
+	/*
+	 * Since run queues may be manipulated by both the statclock and tty,
+	 * network, and diskdrivers, clock > tty.
+	 */
+	imask[IPL_CLOCK] |= imask[IPL_TTY];
+	imask[IPL_STATCLOCK] |= imask[IPL_CLOCK];
 
 	/*
-	 * These are pseudo-levels.
+	 * IPL_HIGH must block everything that can manipulate a run queue.
 	 */
-	imask[IPL_NONE] = 0x00000000;
-	imask[IPL_HIGH] = 0xffffffff;
+	imask[IPL_HIGH] |= imask[IPL_STATCLOCK];
 
 	/* And eventually calculate the complete masks. */
 	for (irq = 0; irq < ICU_LEN; irq++) {
 		int irqs = 1 << irq;
 		for (q = intrhand[irq]; q; q = q->ih_next)
 			irqs |= imask[q->ih_level];
-		intrmask[irq] = irqs | SIR_ALLMASK;
+		intrmask[irq] = irqs;
 	}
 
 	/* Lastly, determine which IRQs are actually in use. */