Port-newsmips archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: sharing mips softintr code (Re: generic soft interrupt patch)



In article <030428190330.M0110392%mirage.ceres.dti.ne.jp@localhost>
I wrote:

> In article <20030428092759.44A1953E7F%thoreau.thistledown.com.au@localhost>
> simonb%wasabisystems.com@localhost 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@localhost

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);
+               }
+       }
+}



Home | Main Index | Thread Index | Old Index