Re: sharing mips softintr code (Re: generic soft interrupt patch)
Izumi Tsutsui <[email protected]> Mon, 28 Apr 2003 21:13:09 +0900
| Newsgroups | gmane.os.netbsd.ports.arc,gmane.os.netbsd.ports.mips.devel,gmane.os.netbsd.ports.newsmips |
|---|---|
| Message-ID | <[email protected]> |
In article <[email protected]> I wrote: > In article <[email protected]> > [email protected] 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 [email protected] 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); + } + } +}