Discussion:
sharing mips softintr code (Re: generic soft interrupt patch)
Izumi Tsutsui
2003-04-28 12:13:09 UTC
Permalink
It'd be nice if we could move all softintr support to somewhere under
sys/arch/mips. Most of arc_trap.c should (with these patches) now be
the same as at least the algor, evbmips, mipsco and pmax interrupt.c
and the sbmips and sgimips softintr.c.
Yes, we should share softintr code among all mips ports,
but I wonder how to migrate to shared code..
Ok, I've made a new patch for arc and newsmips with shared
mips/mips/softintr.c and mips/include/softintr.h
for a start point (works on both NEC-JC94 and NWS-5000).

I'm wondering if _IPL_NSOFT should be MD or not,
but I think all IPL_* and spl*() definitions could
be moved into MI <mips/intr.h> eventually so that
ipl_si_to_sr[] can be moved from machdep.c to mips/softintr.c.

Comments?
---
Izumi Tsutsui
***@ceres.dti.ne.jp

Index: arc/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/arc_trap.c 2003/04/27 17:13:01 1.24
+++ arc/arc/arc_trap.c 2003/04/28 12:07:33
@@ -46,6 +46,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/malloc.h>

#include <uvm/uvm_extern.h>

@@ -133,15 +134,14 @@
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) {
+
+ 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 */
@@ -149,30 +149,12 @@
_splset(arc_hardware_intr(status, cause, pc, 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
+ /* software interrupts */
+ ipending &= (MIPS_SOFT_INT_MASK_1|MIPS_SOFT_INT_MASK_0);
+ if (ipending == 0)
+ return;

- /* 'softnet' interrupt */
- if (ipending & MIPS_SOFT_INT_MASK_1) {
- clearsoftnet();
- uvmexp.softs++;
- netintr();
- }
+ _clrsoftintr(ipending);

- /* 'softclock' interrupt */
- if (ipending & MIPS_SOFT_INT_MASK_0) {
- clearsoftclock();
- uvmexp.softs++;
- intrcnt[SOFTCLOCK_INTR]++;
- softclock(NULL);
- }
+ softintr_dispatch(ipending);
}
Index: arc/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/arc/autoconf.c 2002/09/27 02:24:09 1.18
+++ arc/arc/autoconf.c 2003/04/28 12:07:34
@@ -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/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/arc/c_magnum.c 2003/04/27 11:33:36 1.3
+++ arc/arc/c_magnum.c 2003/04/28 12:07:34
@@ -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/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/arc/c_nec_eisa.c 2003/01/31 22:07:52 1.5
+++ arc/arc/c_nec_eisa.c 2003/04/28 12:07:34
@@ -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/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/arc/c_nec_pci.c 2003/01/19 10:06:12 1.4
+++ arc/arc/c_nec_pci.c 2003/04/28 12:07:34
@@ -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/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/arc/locore_machdep.S 2000/06/09 05:07:32 1.8
+++ arc/arc/locore_machdep.S 2003/04/28 12:07:35
@@ -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/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/arc/machdep.c 2003/04/27 17:05:56 1.77
+++ arc/arc/machdep.c 2003/04/28 12:07:35
@@ -180,13 +180,12 @@
*/
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 */
+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 */
};

extern char kernel_text[], edata[], end[];
Index: arc/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/arc/p_dti_arcstation.c 2001/06/13 15:27:17 1.1
+++ arc/arc/p_dti_arcstation.c 2003/04/28 12:07:36
@@ -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/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/arc/p_dti_tyne.c 2001/06/13 15:27:18 1.1
+++ arc/arc/p_dti_tyne.c 2003/04/28 12:07:36
@@ -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/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/arc/p_sni_rm200pci.c 2001/06/13 15:36:44 1.1
+++ arc/arc/p_sni_rm200pci.c 2003/04/28 12:07:36
@@ -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: arc/conf/files.arc
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/conf/files.arc,v
retrieving revision 1.42
diff -u -r1.42 files.arc
--- arc/conf/files.arc 2003/04/06 09:55:50 1.42
+++ arc/conf/files.arc 2003/04/28 12:07:36
@@ -80,6 +80,9 @@

file arch/arc/arc/arcbios.c

+# XXX should be in mips/conf/files.mips
+file arch/mips/mips/softintr.c
+
##
## Machine-independent ATAPI drivers
##
Index: arc/conf/std.arc
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/conf/std.arc,v
retrieving revision 1.14
diff -u -r1.14 std.arc
--- arc/conf/std.arc 2003/04/28 05:03:44 1.14
+++ arc/conf/std.arc 2003/04/28 12:07:36
@@ -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: arc/include/intr.h
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/include/intr.h,v
retrieving revision 1.10
diff -u -r1.10 intr.h
--- arc/include/intr.h 2001/06/13 15:08:06 1.10
+++ arc/include/intr.h 2003/04/28 12:07:36
@@ -1,8 +1,12 @@
/* $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
* are met:
@@ -13,38 +17,58 @@
* 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 */
@@ -52,86 +76,45 @@
#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>

-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;

-/*
- * 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 */

-struct splvec {
- int splbio;
- int splnet;
- int spltty;
- int splvm;
- int splclock;
- int splstatclock;
-};
-extern struct splvec splvec;
+#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])

-/*
- * Index into intrcnt[], which is defined in locore
- */
-#define SOFTCLOCK_INTR 0
-#define SOFTNET_INTR 1
-#define FPU_INTR 2
-extern u_long intrcnt[];
+#define spllowersoftclock() _spllower(ipl_sr_bits[IPL_SOFTCLOCK])

-struct clockframe;
-void arc_set_intr __P((int, int(*)(u_int, struct clockframe *), int));
+#include <mips/softintr.h>

-/* XXX - revisit here */
-int imask[NIPL];
+struct clockframe;
+void arc_set_intr(int, int(*)(u_int, struct clockframe *), int);

#endif /* !_LOCORE */
#endif /* _KERNEL */
Index: arc/include/types.h
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/include/types.h,v
retrieving revision 1.13
diff -u -r1.13 types.h
--- arc/include/types.h 2002/03/05 16:12:36 1.13
+++ arc/include/types.h 2003/04/28 12:07:36
@@ -6,6 +6,7 @@

#include <mips/types.h>

+#define __HAVE_GENERIC_SOFT_INTERRUPTS
#define __HAVE_DEVICE_REGISTER
#define __HAVE_NWSCONS

Index: arc/isa/isabus.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/isa/isabus.c,v
retrieving revision 1.19
diff -u -r1.19 isabus.c
--- arc/isa/isabus.c 2003/04/27 17:05:58 1.19
+++ arc/isa/isabus.c 2003/04/28 12:07:37
@@ -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. */
Index: newsmips/apbus/apbus.c
===================================================================
RCS file: /cvsroot/src/sys/arch/newsmips/apbus/apbus.c,v
retrieving revision 1.13
diff -u -r1.13 apbus.c
--- newsmips/apbus/apbus.c 2003/04/19 14:56:05 1.13
+++ newsmips/apbus/apbus.c 2003/04/28 12:07:38
@@ -38,6 +38,7 @@
#include <machine/autoconf.h>
#define _NEWSMIPS_BUS_DMA_PRIVATE
#include <machine/bus.h>
+#include <machine/intr.h>
#include <newsmips/apbus/apbusvar.h>

static int apbusmatch (struct device *, struct cfdata *, void *);
@@ -71,21 +72,8 @@
CFATTACH_DECL(ap, sizeof(struct apbus_softc),
apbusmatch, apbusattach, NULL, NULL);

-#define APBUS_DEVNAMELEN 16
-
-struct ap_intrhand {
- struct ap_intrhand *ai_next;
- int ai_mask;
- int ai_priority;
- int (*ai_func) (void*); /* function */
- void *ai_aux; /* softc */
- char ai_name[APBUS_DEVNAMELEN];
- int ai_ctlno;
-};
-
#define NLEVEL 2
-
-static struct ap_intrhand *apintr[NLEVEL];
+static struct newsmips_intr apintr_tab[NLEVEL];

static int
apbusmatch(parent, cfdata, aux)
@@ -111,6 +99,8 @@
struct apbus_attach_args child;
struct apbus_dev *apdev;
struct apbus_ctl *apctl;
+ struct newsmips_intr *ip;
+ int i;

*(volatile u_int *)(NEWS5000_APBUS_INTST) = 0xffffffff;
*(volatile u_int *)(NEWS5000_APBUS_INTMSK) = 0xffffffff;
@@ -119,6 +109,11 @@

printf("\n");

+ for (i = 0; i < NLEVEL; i++) {
+ ip = &apintr_tab[i];
+ LIST_INIT(&ip->intr_q);
+ }
+
/*
* get first ap-device
*/
@@ -202,13 +197,16 @@
int level;
int stat;
{
- int nintr = 0;
- struct ap_intrhand *ai;
-
- for (ai = apintr[level]; ai != NULL; ai = ai->ai_next) {
- if (ai->ai_mask & stat) {
- nintr += (*ai->ai_func)(ai->ai_aux);
- }
+ struct newsmips_intr *ip;
+ struct newsmips_intrhand *ih;
+ int nintr;
+
+ ip = &apintr_tab[level];
+
+ nintr = 0;
+ LIST_FOREACH(ih, &ip->intr_q, ih_q) {
+ if (ih->ih_mask & stat)
+ nintr += (*ih->ih_func)(ih->ih_arg);
}
return nintr;
}
@@ -217,45 +215,58 @@
* register device interrupt routine
*/
void *
-apbus_intr_establish(level, mask, priority, func, aux, name, ctlno)
+apbus_intr_establish(level, mask, priority, func, arg, name, ctlno)
int level;
int mask;
int priority;
int (*func) (void *);
- void *aux;
+ void *arg;
char *name;
int ctlno;
{
- struct ap_intrhand *ai, **aip;
- volatile unsigned int *inten0 = (volatile unsigned int *)NEWS5000_INTEN0;
- volatile unsigned int *inten1 = (volatile unsigned int *)NEWS5000_INTEN1;
+ struct newsmips_intr *ip;
+ struct newsmips_intrhand *ih, *curih;
+ volatile u_int32_t *inten0, *inten1;
+
+ ip = &apintr_tab[level];

- ai = malloc(sizeof(*ai), M_DEVBUF, M_NOWAIT);
- if (ai == NULL)
+ ih = malloc(sizeof(*ih), M_DEVBUF, M_NOWAIT);
+ if (ih == NULL)
panic("apbus_intr_establish: can't malloc handler info");
- ai->ai_mask = mask;
- ai->ai_priority = priority;
- ai->ai_func = func;
- ai->ai_aux = aux;
- strncpy(ai->ai_name, name, APBUS_DEVNAMELEN-1);
- ai->ai_ctlno = ctlno;
-
- for (aip = &apintr[level]; *aip != NULL; aip = &(*aip)->ai_next) {
- if ((*aip)->ai_priority < priority)
- break;
+ ih->ih_mask = mask;
+ ih->ih_priority = priority;
+ ih->ih_func = func;
+ ih->ih_arg = arg;
+
+ if (LIST_EMPTY(&ip->intr_q)) {
+ LIST_INSERT_HEAD(&ip->intr_q, ih, ih_q);
+ goto done;
}
- ai->ai_next = *aip;
- *aip = ai;
+
+ for (curih = LIST_FIRST(&ip->intr_q);
+ LIST_NEXT(curih, ih_q) != NULL;
+ curih = LIST_NEXT(curih, ih_q)) {
+ if (ih->ih_priority > curih->ih_priority) {
+ LIST_INSERT_BEFORE(curih, ih, ih_q);
+ goto done;
+ }
+ }
+
+ LIST_INSERT_AFTER(curih, ih, ih_q);
+
+ done:
switch (level) {
case 0:
+ inten0 = (volatile u_int32_t *)NEWS5000_INTEN0;
*inten0 |= mask;
break;
case 1:
+ inten1 = (volatile u_int32_t *)NEWS5000_INTEN1;
*inten1 |= mask;
break;
}

- return (void *)ai;
+ return (void *)ih;
}

static void
Index: newsmips/apbus/zs_ap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/newsmips/apbus/zs_ap.c,v
retrieving revision 1.13
diff -u -r1.13 zs_ap.c
--- newsmips/apbus/zs_ap.c 2003/04/26 18:43:19 1.13
+++ newsmips/apbus/zs_ap.c 2003/04/28 12:07:39
@@ -311,6 +311,7 @@
if (!didintr) {
didintr = 1;

+ zsc->zsc_si = softintr_establish(IPL_SOFTSERIAL, zssoft, zsc);
apbus_intr_establish(1, /* interrupt level ( 0 or 1 ) */
NEWS5000_INT1_SCC,
0, /* priority */
Index: newsmips/conf/files.newsmips
===================================================================
RCS file: /cvsroot/src/sys/arch/newsmips/conf/files.newsmips,v
retrieving revision 1.21
diff -u -r1.21 files.newsmips
--- newsmips/conf/files.newsmips 2002/10/26 13:50:38 1.21
+++ newsmips/conf/files.newsmips 2003/04/28 12:07:39
@@ -98,6 +98,9 @@
file dev/clock_subr.c
file dev/cons.c

+# XXX should be in mips/conf/files.mips
+file arch/mips/mips/softintr.c
+
#
# Machine-independent SCSI driver.
#
Index: newsmips/dev/hb.c
===================================================================
RCS file: /cvsroot/src/sys/arch/newsmips/dev/hb.c,v
retrieving revision 1.10
diff -u -r1.10 hb.c
--- newsmips/dev/hb.c 2003/01/01 01:55:42 1.10
+++ newsmips/dev/hb.c 2003/04/28 12:07:39
@@ -3,8 +3,10 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
+#include <sys/malloc.h>

#include <machine/autoconf.h>
+#include <machine/intr.h>

static int hb_match __P((struct device *, struct cfdata *, void *));
static void hb_attach __P((struct device *, struct device *, void *));
@@ -17,13 +19,8 @@

extern struct cfdriver hb_cd;

-struct intrhand {
- int (*func) __P((void *));
- void *arg;
-};
-
-#define NHBINTR 4
-struct intrhand hb_intrhand[6][NHBINTR];
+#define NLEVEL 4
+static struct newsmips_intr hbintr_tab[NLEVEL];

static int
hb_match(parent, cf, aux)
@@ -46,8 +43,16 @@
void *aux;
{
struct confargs *ca = aux;
+ struct newsmips_intr *ip;
+ int i;

printf("\n");
+
+ for (i = 0; i < NLEVEL; i++) {
+ ip = &hbintr_tab[i];
+ LIST_INIT(&ip->intr_q);
+ }
+
config_search(hb_search, self, ca);
}

@@ -90,50 +95,53 @@
}

void *
-hb_intr_establish(irq, level, func, arg)
- int irq, level;
+hb_intr_establish(level, priority, func, arg)
+ int level, priority;
int (*func) __P((void *));
void *arg;
{
- struct intrhand *ih = hb_intrhand[irq];
- int i;
+ struct newsmips_intr *ip;
+ struct newsmips_intrhand *ih, *curih;
+
+ ip = &hbintr_tab[level];

- for (i = NHBINTR; i > 0; i--) {
- if (ih->func == NULL)
- goto found;
- ih++;
+ ih = malloc(sizeof *ih, M_DEVBUF, M_NOWAIT);
+ if (ih == NULL)
+ panic("hb_intr_establish: malloc failed");
+
+ ih->ih_func = func;
+ ih->ih_arg = arg;
+ ih->ih_priority = priority;
+ if (LIST_EMPTY(&ip->intr_q)) {
+ LIST_INSERT_HEAD(&ip->intr_q, ih, ih_q);
+ goto done;
}
- panic("hb_intr_establish: no room");

-found:
- ih->func = func;
- ih->arg = arg;
-
-#ifdef HB_DEBUG
- for (irq = 0; irq <= 2; irq++) {
- for (i = 0; i < NHBINTR; i++) {
- printf("%p(%p) ",
- hb_intrhand[irq][i].func,
- hb_intrhand[irq][i].arg);
+ for (curih = LIST_FIRST(&ip->intr_q);
+ LIST_NEXT(curih, ih_q) != NULL;
+ curih = LIST_NEXT(curih, ih_q)) {
+ if (ih->ih_priority > curih->ih_priority) {
+ LIST_INSERT_BEFORE(curih, ih, ih_q);
+ goto done;
}
- printf("\n");
}
-#endif

+ LIST_INSERT_AFTER(curih, ih, ih_q);
+
+ done:
return ih;
}

void
-hb_intr_dispatch(irq)
- int irq;
+hb_intr_dispatch(level)
+ int level;
{
- struct intrhand *ih;
- int i;
+ struct newsmips_intr *ip;
+ struct newsmips_intrhand *ih;
+
+ ip = &hbintr_tab[level];

- ih = hb_intrhand[irq];
- for (i = NHBINTR; i > 0; i--) {
- if (ih->func)
- (*ih->func)(ih->arg);
- ih++;
+ LIST_FOREACH(ih, &ip->intr_q, ih_q) {
+ (*ih->ih_func)(ih->ih_arg);
}
}
Index: newsmips/dev/zs.c
===================================================================
RCS file: /cvsroot/src/sys/arch/newsmips/dev/zs.c,v
retrieving revision 1.17
diff -u -r1.17 zs.c
--- newsmips/dev/zs.c 2003/04/26 18:43:20 1.17
+++ newsmips/dev/zs.c 2003/04/28 12:07:39
@@ -84,8 +84,6 @@
return UNCONF;
}

-static volatile int zssoftpending;
-
/*
* Our ZS chips all share a common, autovectored interrupt,
* so we have to look at all of them on each interrupt.
@@ -97,20 +95,16 @@
struct zsc_softc *zsc;
int unit, rval, softreq;

- rval = softreq = 0;
+ rval = 0;
for (unit = 0; unit < zsc_cd.cd_ndevs; unit++) {
zsc = zsc_cd.cd_devs[unit];
if (zsc == NULL)
continue;
rval |= zsc_intr_hard(zsc);
- softreq |= zsc->zsc_cs[0]->cs_softreq;
+ softreq = zsc->zsc_cs[0]->cs_softreq;
softreq |= zsc->zsc_cs[1]->cs_softreq;
- }
-
- /* We are at splzs here, so no need to lock. */
- if (softreq && (zssoftpending == 0)) {
- zssoftpending = 1;
- setsoftserial();
+ if (softreq)
+ softintr_schedule(zsc->zsc_si);
}

return rval;
@@ -126,19 +120,6 @@
struct zsc_softc *zsc;
int s, unit;

- /* This is not the only ISR on this IPL. */
- if (zssoftpending == 0)
- return;
-
- /*
- * The soft intr. bit will be set by zshard only if
- * the variable zssoftpending is zero. The order of
- * these next two statements prevents our clearing
- * the soft intr bit just after zshard has set it.
- */
- /* clearsoftnet(); */
- zssoftpending = 0;
-
/* Make sure we call the tty layer at spltty. */
s = spltty();
for (unit = 0; unit < zsc_cd.cd_ndevs; unit++) {
@@ -214,7 +195,7 @@
* Therefore, NEVER set the HFC bit, and instead use the
* status interrupt to detect CTS changes.
*/
- s = splzs();
+ s = splserial();
cs->cs_rr0_pps = 0;
if ((cflag & (CLOCAL | MDMBUF)) != 0) {
cs->cs_rr0_dcd = 0;
Index: newsmips/dev/zs_hb.c
===================================================================
RCS file: /cvsroot/src/sys/arch/newsmips/dev/zs_hb.c,v
retrieving revision 1.11
diff -u -r1.11 zs_hb.c
--- newsmips/dev/zs_hb.c 2003/04/26 18:43:20 1.11
+++ newsmips/dev/zs_hb.c 2003/04/28 12:07:39
@@ -295,6 +295,7 @@
if (!didintr) {
didintr = 1;

+ zsc->zsc_si = softintr_establish(IPL_SOFTSERIAL, zssoft, zsc);
hb_intr_establish(intlevel, IPL_SERIAL, zshard_hb, NULL);
}
/* XXX; evcnt_attach() ? */
Index: newsmips/include/intr.h
===================================================================
RCS file: /cvsroot/src/sys/arch/newsmips/include/intr.h,v
retrieving revision 1.11
diff -u -r1.11 intr.h
--- newsmips/include/intr.h 2001/04/13 23:30:02 1.11
+++ newsmips/include/intr.h 2003/04/28 12:07:40
@@ -1,7 +1,11 @@
/* $NetBSD: intr.h,v 1.11 2001/04/13 23:30:02 thorpej 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,39 +17,66 @@
* 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 _MACHINE_INTR_H_
#define _MACHINE_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_CLOCK 4 /* disable clock interrupts */
-#define IPL_STATCLOCK 5 /* disable profiling interrupts */
-#define IPL_SERIAL 6 /* disable serial hardware interrupts */
-#define IPL_HIGH 7 /* disable all interrupts */

+#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 */
+#define IPL_CLOCK 8 /* disable clock interrupts */
+#define IPL_STATCLOCK 8 /* disable profiling interrupts */
+#define IPL_HIGH 8 /* disable all interrupts */
+
+#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", \
+}
+
#ifdef _KERNEL
#ifndef _LOCORE
-#include <mips/cpuregs.h>

+#include <sys/device.h>
+
+extern const u_int32_t ipl_sr_bits[_IPL_N];
+
extern int _splraise __P((int));
extern int _spllower __P((int));
extern int _splset __P((int));
@@ -54,81 +85,73 @@
extern void _setsoftintr __P((int));
extern void _clrsoftintr __P((int));

-/*
- * software simulated interrupt
- */
-#define SIR_NET 0x01
-#define SIR_SERIAL 0x02
-
-#define setsoft(x) do { \
- extern u_int ssir; \
- int s; \
- \
- s = splhigh(); \
- ssir |= (x); \
- _setsoftintr(MIPS_SOFT_INT_MASK_1); \
- splx(s); \
-} while (0)
-
-#define setsoftclock() _setsoftintr(MIPS_SOFT_INT_MASK_0)
-#define setsoftnet() setsoft(SIR_NET)
-#define setsoftserial() setsoft(SIR_SERIAL)
-
-/*
- * 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 splhigh() _splraise(ipl_sr_bits[IPL_HIGH])
#define spl0() (void)_spllower(0)
#define splx(s) (void)_splset(s)
-#define splbio() _splraise(MIPS_INT_MASK_SPL0)
-#define splnet() _splraise(MIPS_INT_MASK_SPL1)
-#define spltty() _splraise(MIPS_INT_MASK_SPL1)
-#define splvm() _splraise(MIPS_INT_MASK_SPL1)
-#define splclock() _splraise(MIPS_INT_MASK_SPL2)
-#define splstatclock() _splraise(MIPS_INT_MASK_SPL2)
-#define splhigh() _splraise(MIPS_INT_MASK_SPL2)
-#define splsched() splhigh()
-#define spllock() 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() splclock()
+#define spllock() splhigh()
+
+#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])
+
+struct newsmips_intrhand {
+ LIST_ENTRY(newsmips_intrhand) ih_q;
+ struct evcnt intr_count;
+ int (*ih_func)(void *);
+ void *ih_arg;
+ u_int ih_level;
+ u_int ih_mask;
+ u_int ih_priority;
+};
+
+struct newsmips_intr {
+ LIST_HEAD(,newsmips_intrhand) intr_q;
+};
+
+#include <mips/softintr.h>

/*
* Index into intrcnt[], which is defined in locore
*/
-#define SOFTCLOCK_INTR 0
-#define SOFTNET_INTR 1
-#define SERIAL0_INTR 2
-#define SERIAL1_INTR 3
-#define SERIAL2_INTR 4
-#define LANCE_INTR 5
-#define SCSI_INTR 6
-#define ERROR_INTR 7
-#define HARDCLOCK_INTR 8
-#define FPU_INTR 9
-#define SLOT1_INTR 10
-#define SLOT2_INTR 11
-#define SLOT3_INTR 12
-#define FLOPPY_INTR 13
-#define STRAY_INTR 14
+#define SERIAL0_INTR 0
+#define SERIAL1_INTR 1
+#define SERIAL2_INTR 2
+#define LANCE_INTR 3
+#define SCSI_INTR 4
+#define ERROR_INTR 5
+#define HARDCLOCK_INTR 6
+#define FPU_INTR 7
+#define SLOT1_INTR 8
+#define SLOT2_INTR 9
+#define SLOT3_INTR 10
+#define FLOPPY_INTR 11
+#define STRAY_INTR 12

extern u_int intrcnt[];

/* handle i/o device interrupts */
-extern void news3400_intr __P((u_int, u_int, u_int, u_int));
-extern void news5000_intr __P((u_int, u_int, u_int, u_int));
+#ifdef news3400
+void news3400_intr __P((u_int, u_int, u_int, u_int));
+#endif
+#ifdef news5000
+void news5000_intr __P((u_int, u_int, u_int, u_int));
+#endif
+void (*hardware_intr) __P((u_int, u_int, u_int, u_int));

-extern void (*enable_intr) __P((void));
-extern void (*disable_intr) __P((void));
+void (*enable_intr) __P((void));
+void (*disable_intr) __P((void));

#endif /* !_LOCORE */
#endif /* _KERNEL */
Index: newsmips/include/types.h
===================================================================
RCS file: /cvsroot/src/sys/arch/newsmips/include/types.h,v
retrieving revision 1.5
diff -u -r1.5 types.h
--- newsmips/include/types.h 2002/08/05 02:13:15 1.5
+++ newsmips/include/types.h 2003/04/28 12:07:40
@@ -3,6 +3,7 @@
#include <mips/types.h>

#define __BROKEN_CONFIG_UNIT_USAGE
+#define __HAVE_GENERIC_SOFT_INTERRUPTS

/* MIPS specific options */
#define __HAVE_BOOTINFO_H
Index: newsmips/include/z8530var.h
===================================================================
RCS file: /cvsroot/src/sys/arch/newsmips/include/z8530var.h,v
retrieving revision 1.4
diff -u -r1.4 z8530var.h
--- newsmips/include/z8530var.h 2003/04/26 18:43:20 1.4
+++ newsmips/include/z8530var.h 2003/04/28 12:07:40
@@ -52,6 +52,7 @@
struct zs_chanstate *zsc_cs[2]; /* channel A and B soft state */
/* Machine-dependent part follows... */
struct zs_chanstate zsc_cs_store[2];
+ void *zsc_si; /* softinterrupt handle */
};

/*
@@ -76,6 +77,4 @@
int zs_get_speed __P((struct zs_chanstate *));
void (*zs_delay) __P((void));

-/* Zilog Serial hardware interrupts (level 1) */
-#define splzs cpu_spl1
-extern int splzs(void);
+#define splzs() splserial()
Index: newsmips/newsmips/autoconf.c
===================================================================
RCS file: /cvsroot/src/sys/arch/newsmips/newsmips/autoconf.c,v
retrieving revision 1.16
diff -u -r1.16 autoconf.c
--- newsmips/newsmips/autoconf.c 2002/09/25 22:21:15 1.16
+++ newsmips/newsmips/autoconf.c 2003/04/28 12:07:40
@@ -98,6 +98,7 @@
/*
* Kick off autoconfiguration
*/
+ softintr_init();
_splnone(); /* enable all interrupts */
splhigh(); /* ...then disable device interrupts */

Index: newsmips/newsmips/locore_machdep.S
===================================================================
RCS file: /cvsroot/src/sys/arch/newsmips/newsmips/locore_machdep.S,v
retrieving revision 1.9
diff -u -r1.9 locore_machdep.S
--- newsmips/newsmips/locore_machdep.S 2003/04/26 18:40:00 1.9
+++ newsmips/newsmips/locore_machdep.S 2003/04/28 12:07:40
@@ -226,8 +226,6 @@
.globl _C_LABEL(intrnames)
.globl _C_LABEL(eintrnames)
_C_LABEL(intrnames):
- .asciiz "softclock"
- .asciiz "softnet"
.asciiz "serial0"
.asciiz "serial1"
.asciiz "serial2"
@@ -246,7 +244,7 @@
_C_LABEL(eintrnames):
.align 2
_C_LABEL(intrcnt):
- .word 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0
+ .word 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0
_C_LABEL(eintrcnt):
.word 0 # This shouldn't be needed but with 4.4bsd's as, the eintrcnt
# label ends end up in a different section otherwise.
Index: newsmips/newsmips/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/newsmips/newsmips/machdep.c,v
retrieving revision 1.69
diff -u -r1.69 machdep.c
--- newsmips/newsmips/machdep.c 2003/04/26 18:50:19 1.69
+++ newsmips/newsmips/machdep.c 2003/04/28 12:07:41
@@ -78,6 +78,7 @@
#include <ufs/mfs/mfs_extern.h> /* mfs_initminiroot() */

#include <machine/cpu.h>
+#include <machine/intr.h>
#include <machine/reg.h>
#include <machine/psl.h>
#include <machine/pte.h>
@@ -129,13 +130,8 @@
int mem_cluster_cnt;

struct idrom idrom;
-void (*enable_intr) __P((void));
-void (*disable_intr) __P((void));
void (*readmicrotime) __P((struct timeval *tvp));

-static void (*hardware_intr) __P((u_int, u_int, u_int, u_int));
-u_int ssir;
-
/*
* Local functions.
*/
@@ -159,6 +155,51 @@
*/
int safepri = MIPS3_PSL_LOWIPL; /* XXX */

+/*
+ * This is a mask of bits to clear in the SR when we go to a
+ * given interrupt priority level.
+ */
+const u_int32_t 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, /* IPL_BIO */
+
+ MIPS_SOFT_INT_MASK_0|
+ MIPS_SOFT_INT_MASK_1|
+ MIPS_INT_MASK_0|
+ MIPS_INT_MASK_1, /* IPL_NET */
+
+ MIPS_SOFT_INT_MASK_0|
+ MIPS_SOFT_INT_MASK_1|
+ MIPS_INT_MASK_0|
+ MIPS_INT_MASK_1, /* 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, /* IPL_{CLOCK,HIGH} */
+};
+
+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 */
+};
+
extern struct user *proc0paddr;
extern u_long bootdev;
extern char edata[], end[];
@@ -651,10 +692,6 @@
DELAY(n);
}

-#include "zsc.h"
-
-int zssoft __P((void));
-
void
cpu_intr(status, cause, pc, ipending)
u_int32_t status;
@@ -662,39 +699,18 @@
u_int32_t pc;
u_int32_t ipending;
{
+
uvmexp.intrs++;

/* device interrupts */
(*hardware_intr)(status, cause, pc, ipending);

- /* software simulated interrupt */
- if ((ipending & MIPS_SOFT_INT_MASK_1) ||
- (ssir && (status & MIPS_SOFT_INT_MASK_1))) {
-
-#define DO_SIR(bit, fn) \
- do { \
- if (n & (bit)) { \
- uvmexp.softs++; \
- fn; \
- } \
- } while (0)
-
- unsigned n;
- n = ssir; ssir = 0;
- _clrsoftintr(MIPS_SOFT_INT_MASK_1);
+ /* software interrupts */
+ ipending &= (MIPS_SOFT_INT_MASK_1|MIPS_SOFT_INT_MASK_0);
+ if (ipending == 0)
+ return;

-#if NZSC > 0
- DO_SIR(SIR_SERIAL, zssoft());
-#endif
- DO_SIR(SIR_NET, netintr());
-#undef DO_SIR
- }
+ _clrsoftintr(ipending);

- /* 'softclock' interrupt */
- if (ipending & MIPS_SOFT_INT_MASK_0) {
- _clrsoftintr(MIPS_SOFT_INT_MASK_0);
- uvmexp.softs++;
- intrcnt[SOFTCLOCK_INTR]++;
- softclock(NULL);
- }
+ softintr_dispatch(ipending);
}
--- /dev/null 2003-04-28 20:00:22.000000000 +0900
+++ mips/include/softintr.h 2003-04-28 19:26:48.000000000 +0900
@@ -0,0 +1,99 @@
+/* $NetBSD$ */
+
+/*-
+ * 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
+ * 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.
+ */
+
+#ifndef _MIPS_SOFTINTR_H_
+#define _MIPS_SOFTINTR_H_
+
+#ifdef _KERNEL
+#ifndef _LOCORE
+
+#include <sys/device.h>
+#include <sys/lock.h>
+
+extern const u_int32_t ipl_si_to_sr[_IPL_NSOFT];
+
+#define setsoft(x) \
+do { \
+ _setsoftintr(ipl_si_to_sr[(x) - IPL_SOFT]); \
+} while (/*CONSTCOND*/0)
+
+struct mips_soft_intrhand {
+ TAILQ_ENTRY(mips_soft_intrhand) sih_q;
+ struct mips_soft_intr *sih_intrhead;
+ void (*sih_func)(void *);
+ void *sih_arg;
+ int sih_pending;
+};
+
+struct mips_soft_intr {
+ TAILQ_HEAD(,mips_soft_intrhand) softintr_q;
+ struct evcnt softintr_evcnt;
+ struct simplelock softintr_slock;
+ unsigned long softintr_ipl;
+};
+
+void softintr_init(void);
+void *softintr_establish(int, void (*)(void *), void *);
+void softintr_disestablish(void *);
+void softintr_dispatch(u_int32_t);
+
+#define softintr_schedule(arg) \
+do { \
+ struct mips_soft_intrhand *__sih = (arg); \
+ struct mips_soft_intr *__msi = __sih->sih_intrhead; \
+ int __s; \
+ \
+ __s = splhigh(); \
+ simple_lock(&__msi->softintr_slock); \
+ if (__sih->sih_pending == 0) { \
+ TAILQ_INSERT_TAIL(&__msi->softintr_q, __sih, sih_q); \
+ __sih->sih_pending = 1; \
+ setsoft(__msi->softintr_ipl); \
+ } \
+ simple_unlock(&__msi->softintr_slock); \
+ splx(__s); \
+} while (/*CONSTCOND*/0)
+
+/* XXX For legacy software interrupts. */
+extern struct mips_soft_intrhand *softnet_intrhand;
+
+#define setsoftnet() softintr_schedule(softnet_intrhand)
+
+#endif /* !_LOCORE */
+#endif /* _KERNEL */
+#endif /* _MIPS_SOFTINTR_H_ */
--- /dev/null 2003-04-28 20:00:22.000000000 +0900
+++ mips/mips/softintr.c 2003-04-28 20:41:55.000000000 +0900
@@ -0,0 +1,172 @@
+/* $NetBSD$ */
+
+/*
+ * 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.
+ */
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <net/netisr.h> /* Legacy softnet support */
+
+#include <machine/intr.h>
+
+/* XXX For legacy software interrupts. */
+struct mips_soft_intrhand *softnet_intrhand;
+
+struct mips_soft_intr mips_soft_intrs[_IPL_NSOFT];
+
+/*
+ * softintr_init:
+ *
+ * Initialize the software interrupt system.
+ */
+void
+softintr_init(void)
+{
+ static const char *softintr_names[] = IPL_SOFTNAMES;
+ struct mips_soft_intr *msi;
+ int i;
+
+ for (i = 0; i < _IPL_NSOFT; i++) {
+ msi = &mips_soft_intrs[i];
+ TAILQ_INIT(&msi->softintr_q);
+ msi->softintr_ipl = IPL_SOFT + i;
+ evcnt_attach_dynamic(&msi->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 mips_soft_intr *msi;
+ struct mips_soft_intrhand *sih;
+
+ if (__predict_false(ipl >= (IPL_SOFT + _IPL_NSOFT) ||
+ ipl < IPL_SOFT))
+ panic("softintr_establish");
+
+ msi = &mips_soft_intrs[ipl - IPL_SOFT];
+
+ sih = malloc(sizeof(*sih), M_DEVBUF, M_NOWAIT);
+ if (__predict_true(sih != NULL)) {
+ sih->sih_intrhead = msi;
+ 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 mips_soft_intrhand *sih = arg;
+ struct mips_soft_intr *msi = sih->sih_intrhead;
+ int s;
+
+ s = splhigh();
+ if (sih->sih_pending) {
+ TAILQ_REMOVE(&msi->softintr_q, sih, sih_q);
+ sih->sih_pending = 0;
+ }
+ splx(s);
+
+ free(sih, M_DEVBUF);
+}
+
+/*
+ * softintr_dispatch:
+ *
+ * Process pending software interrupts.
+ *
+ * Called at splsoft()
+ */
+void
+softintr_dispatch(ipending)
+ u_int32_t ipending;
+{
+ struct mips_soft_intr *msi;
+ struct mips_soft_intrhand *sih;
+ int i, s;
+
+ for (i = _IPL_NSOFT - 1; i >= 0; i--) {
+ if ((ipending & ipl_si_to_sr[i]) == 0)
+ continue;
+
+ msi = &mips_soft_intrs[i];
+
+ if (TAILQ_FIRST(&msi->softintr_q) != NULL)
+ msi->softintr_evcnt.ev_count++;
+
+ for (;;) {
+ s = splhigh();
+
+ sih = TAILQ_FIRST(&msi->softintr_q);
+ if (sih != NULL) {
+ TAILQ_REMOVE(&msi->softintr_q, sih, sih_q);
+ sih->sih_pending = 0;
+ }
+
+ splx(s);
+
+ if (sih == NULL)
+ break;
+
+ uvmexp.softs++;
+ (*sih->sih_func)(sih->sih_arg);
+ }
+ }
+}

Loading...