Subject: Re: sharing mips softintr code (Re: generic soft interrupt patch)
To: None <simonb@wasabisystems.com, port-mips@netbsd.org>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: port-newsmips
Date: 04/28/2003 21:13:09
In article <030428190330.M0110392@mirage.ceres.dti.ne.jp>
I wrote:
> In article <20030428092759.44A1953E7F@thoreau.thistledown.com.au>
> simonb@wasabisystems.com wrote:
>
> > 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
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);
+ }
+ }
+}