diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2002-04-30 01:12:30 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2002-04-30 01:12:30 +0000 |
commit | 88066c9a0811bfa66b9e85d8790cbfab53d8d481 (patch) | |
tree | ad08df2b2e5d355769383393b043398e0c0dc4b0 /sys | |
parent | 953dd9ca5783b67d25ed99deab898083deb94c3f (diff) |
Fix an ancient problem in how sparc interrupts are handled.
There are many interrupt handlers that assume that they don't need to do
any spl protection in their code because the interrupt of some level can't
be interrupted by an interrupt of the same level. The problem is that some
interrupt handlers have hardware levels that are lower then their "software"
levels.
Fix this by adding an additional field to struct intrhand that specifies which
"software" level an interrupt handler has and blocks that level while handling
the interrupt. This new field is initialized in intr_establish which gets
an additional argument (which can be -1 meaning that the interrupt handler
doesn't need to block any additional level).
ok deraadt@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/sparc/dev/amd7930.c | 6 | ||||
-rw-r--r-- | sys/arch/sparc/dev/be.c | 4 | ||||
-rw-r--r-- | sys/arch/sparc/dev/cs4231.c | 4 | ||||
-rw-r--r-- | sys/arch/sparc/dev/esp.c | 4 | ||||
-rw-r--r-- | sys/arch/sparc/dev/fd.c | 6 | ||||
-rw-r--r-- | sys/arch/sparc/dev/fga.c | 16 | ||||
-rw-r--r-- | sys/arch/sparc/dev/hme.c | 4 | ||||
-rw-r--r-- | sys/arch/sparc/dev/if_en_sbus.c | 4 | ||||
-rw-r--r-- | sys/arch/sparc/dev/if_ie.c | 6 | ||||
-rw-r--r-- | sys/arch/sparc/dev/if_le.c | 4 | ||||
-rw-r--r-- | sys/arch/sparc/dev/isp_sbus.c | 4 | ||||
-rw-r--r-- | sys/arch/sparc/dev/magma.c | 6 | ||||
-rw-r--r-- | sys/arch/sparc/dev/obio.c | 7 | ||||
-rw-r--r-- | sys/arch/sparc/dev/qe.c | 4 | ||||
-rw-r--r-- | sys/arch/sparc/dev/si.c | 6 | ||||
-rw-r--r-- | sys/arch/sparc/dev/spif.c | 8 | ||||
-rw-r--r-- | sys/arch/sparc/dev/tctrl.c | 4 | ||||
-rw-r--r-- | sys/arch/sparc/dev/xd.c | 4 | ||||
-rw-r--r-- | sys/arch/sparc/dev/xy.c | 4 | ||||
-rw-r--r-- | sys/arch/sparc/dev/zs.c | 6 | ||||
-rw-r--r-- | sys/arch/sparc/include/cpu.h | 9 | ||||
-rw-r--r-- | sys/arch/sparc/sparc/genassym.cf | 3 | ||||
-rw-r--r-- | sys/arch/sparc/sparc/intr.c | 34 | ||||
-rw-r--r-- | sys/arch/sparc/sparc/locore.s | 14 |
24 files changed, 104 insertions, 67 deletions
diff --git a/sys/arch/sparc/dev/amd7930.c b/sys/arch/sparc/dev/amd7930.c index 5bc0871aaee..28bed7df5fb 100644 --- a/sys/arch/sparc/dev/amd7930.c +++ b/sys/arch/sparc/dev/amd7930.c @@ -1,4 +1,4 @@ -/* $OpenBSD: amd7930.c,v 1.21 2002/04/28 03:51:19 art Exp $ */ +/* $OpenBSD: amd7930.c,v 1.22 2002/04/30 01:12:28 art Exp $ */ /* $NetBSD: amd7930.c,v 1.37 1998/03/30 14:23:40 pk Exp $ */ /* @@ -304,11 +304,11 @@ amd7930attach(parent, self, args) #else sc->sc_hwih.ih_fun = amd7930hwintr; sc->sc_hwih.ih_arg = &sc->sc_au; - intr_establish(pri, &sc->sc_hwih); + intr_establish(pri, &sc->sc_hwih, IPL_AUHARD); #endif sc->sc_swih.ih_fun = amd7930swintr; sc->sc_swih.ih_arg = sc; - intr_establish(IPL_AUSOFT, &sc->sc_swih); + intr_establish(IPL_AUSOFT, &sc->sc_swih, IPL_AUSOFT); evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt); diff --git a/sys/arch/sparc/dev/be.c b/sys/arch/sparc/dev/be.c index b32ed103c4a..fb1641b3081 100644 --- a/sys/arch/sparc/dev/be.c +++ b/sys/arch/sparc/dev/be.c @@ -1,4 +1,4 @@ -/* $OpenBSD: be.c,v 1.31 2002/03/14 01:26:42 millert Exp $ */ +/* $OpenBSD: be.c,v 1.32 2002/04/30 01:12:28 art Exp $ */ /* * Copyright (c) 1998 Theo de Raadt and Jason L. Wright. @@ -160,7 +160,7 @@ beattach(parent, self, aux) sc->sc_ih.ih_fun = beintr; sc->sc_ih.ih_arg = sc; - intr_establish(pri, &sc->sc_ih); + intr_establish(pri, &sc->sc_ih, IPL_NET); myetheraddr(sc->sc_arpcom.ac_enaddr); diff --git a/sys/arch/sparc/dev/cs4231.c b/sys/arch/sparc/dev/cs4231.c index b8199ad859b..9623d92af35 100644 --- a/sys/arch/sparc/dev/cs4231.c +++ b/sys/arch/sparc/dev/cs4231.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cs4231.c,v 1.14 2002/04/28 03:51:19 art Exp $ */ +/* $OpenBSD: cs4231.c,v 1.15 2002/04/30 01:12:29 art Exp $ */ /* * Copyright (c) 1999 Jason L. Wright (jason@thought.net) @@ -239,7 +239,7 @@ cs4231_attach(parent, self, aux) sc->sc_ih.ih_fun = cs4231_intr; sc->sc_ih.ih_arg = sc; - intr_establish(ca->ca_ra.ra_intr[0].int_pri, &sc->sc_ih); + intr_establish(ca->ca_ra.ra_intr[0].int_pri, &sc->sc_ih, IPL_AUHARD); printf(" pri %d, softpri %d\n", pri, IPL_AUSOFT); diff --git a/sys/arch/sparc/dev/esp.c b/sys/arch/sparc/dev/esp.c index feacd96c0a2..bc97c794a1a 100644 --- a/sys/arch/sparc/dev/esp.c +++ b/sys/arch/sparc/dev/esp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: esp.c,v 1.18 2002/03/14 01:26:42 millert Exp $ */ +/* $OpenBSD: esp.c,v 1.19 2002/04/30 01:12:29 art Exp $ */ /* $NetBSD: esp.c,v 1.69 1997/08/27 11:24:18 bouyer Exp $ */ /* @@ -376,7 +376,7 @@ espattach(parent, self, aux) /* and the interuppts */ esc->sc_ih.ih_fun = (void *) ncr53c9x_intr; esc->sc_ih.ih_arg = sc; - intr_establish(esc->sc_pri, &esc->sc_ih); + intr_establish(esc->sc_pri, &esc->sc_ih, IPL_BIO); evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt); /* diff --git a/sys/arch/sparc/dev/fd.c b/sys/arch/sparc/dev/fd.c index 11ee021ee3c..1488213b930 100644 --- a/sys/arch/sparc/dev/fd.c +++ b/sys/arch/sparc/dev/fd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fd.c,v 1.27 2002/04/28 03:51:19 art Exp $ */ +/* $OpenBSD: fd.c,v 1.28 2002/04/30 01:12:29 art Exp $ */ /* $NetBSD: fd.c,v 1.51 1997/05/24 20:16:19 pk Exp $ */ /*- @@ -388,14 +388,14 @@ fdcattach(parent, self, aux) #ifdef FDC_C_HANDLER fdc->sc_hih.ih_fun = (void *)fdchwintr; fdc->sc_hih.ih_arg = fdc; - intr_establish(pri, &fdc->sc_hih); + intr_establish(pri, &fdc->sc_hih, IPL_FD); #else fdciop = &fdc->sc_io; intr_fasttrap(pri, fdchwintr); #endif fdc->sc_sih.ih_fun = (void *)fdcswintr; fdc->sc_sih.ih_arg = fdc; - intr_establish(IPL_FDSOFT, &fdc->sc_sih); + intr_establish(IPL_FDSOFT, &fdc->sc_sih, IPL_BIO); /* Assume a 82077 */ fdc->sc_reg_msr = &((struct fdreg_77 *)fdc->sc_reg)->fd_msr; diff --git a/sys/arch/sparc/dev/fga.c b/sys/arch/sparc/dev/fga.c index 687ec284248..d38be028109 100644 --- a/sys/arch/sparc/dev/fga.c +++ b/sys/arch/sparc/dev/fga.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fga.c,v 1.8 2002/03/14 03:15:59 millert Exp $ */ +/* $OpenBSD: fga.c,v 1.9 2002/04/30 01:12:29 art Exp $ */ /* * Copyright (c) 1999 Jason L. Wright (jason@thought.net) @@ -564,37 +564,37 @@ fga_hwintr_establish(sc, sint) case 1: sc->sc_ih1.ih_fun = fga_hwintr1; sc->sc_ih1.ih_arg = sc; - intr_establish(sint_to_pri[sint], &sc->sc_ih1); + intr_establish(sint_to_pri[sint], &sc->sc_ih1, -1); break; case 2: sc->sc_ih2.ih_fun = fga_hwintr2; sc->sc_ih2.ih_arg = sc; - intr_establish(sint_to_pri[sint], &sc->sc_ih2); + intr_establish(sint_to_pri[sint], &sc->sc_ih2, -1); break; case 3: sc->sc_ih3.ih_fun = fga_hwintr3; sc->sc_ih3.ih_arg = sc; - intr_establish(sint_to_pri[sint], &sc->sc_ih3); + intr_establish(sint_to_pri[sint], &sc->sc_ih3, -1); break; case 4: sc->sc_ih4.ih_fun = fga_hwintr4; sc->sc_ih4.ih_arg = sc; - intr_establish(sint_to_pri[sint], &sc->sc_ih4); + intr_establish(sint_to_pri[sint], &sc->sc_ih4, -1); break; case 5: sc->sc_ih5.ih_fun = fga_hwintr5; sc->sc_ih5.ih_arg = sc; - intr_establish(sint_to_pri[sint], &sc->sc_ih5); + intr_establish(sint_to_pri[sint], &sc->sc_ih5, -1); break; case 6: sc->sc_ih6.ih_fun = fga_hwintr6; sc->sc_ih6.ih_arg = sc; - intr_establish(sint_to_pri[sint], &sc->sc_ih6); + intr_establish(sint_to_pri[sint], &sc->sc_ih6, -1); break; case 7: sc->sc_ih7.ih_fun = fga_hwintr7; sc->sc_ih7.ih_arg = sc; - intr_establish(sint_to_pri[sint], &sc->sc_ih7); + intr_establish(sint_to_pri[sint], &sc->sc_ih7, -1); break; default: panic("fga_sint"); diff --git a/sys/arch/sparc/dev/hme.c b/sys/arch/sparc/dev/hme.c index 7542fe5db19..29b31969950 100644 --- a/sys/arch/sparc/dev/hme.c +++ b/sys/arch/sparc/dev/hme.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hme.c,v 1.35 2002/03/14 01:26:43 millert Exp $ */ +/* $OpenBSD: hme.c,v 1.36 2002/04/30 01:12:29 art Exp $ */ /* * Copyright (c) 1998 Jason L. Wright (jason@thought.net) @@ -210,7 +210,7 @@ hmeattach(parent, self, aux) sc->sc_ih.ih_fun = hmeintr; sc->sc_ih.ih_arg = sc; - intr_establish(ca->ca_ra.ra_intr[0].int_pri, &sc->sc_ih); + intr_establish(ca->ca_ra.ra_intr[0].int_pri, &sc->sc_ih, IPL_NET); /* * Get MAC address from card if 'local-mac-address' property exists. diff --git a/sys/arch/sparc/dev/if_en_sbus.c b/sys/arch/sparc/dev/if_en_sbus.c index 0c73a96b688..fbf5991adae 100644 --- a/sys/arch/sparc/dev/if_en_sbus.c +++ b/sys/arch/sparc/dev/if_en_sbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_en_sbus.c,v 1.4 2002/03/14 01:26:43 millert Exp $ */ +/* $OpenBSD: if_en_sbus.c,v 1.5 2002/04/30 01:12:29 art Exp $ */ /* $NetBSD: if_en_sbus.c,v 1.4 1997/05/24 20:16:22 pk Exp $ */ /* @@ -161,7 +161,7 @@ void *aux; } scs->sc_ih.ih_fun = en_intr; scs->sc_ih.ih_arg = sc; - intr_establish(EN_IPL, &scs->sc_ih); + intr_establish(EN_IPL, &scs->sc_ih, IPL_NET); /* * done SBUS specific stuff diff --git a/sys/arch/sparc/dev/if_ie.c b/sys/arch/sparc/dev/if_ie.c index c6000e5adc6..c510d08b17f 100644 --- a/sys/arch/sparc/dev/if_ie.c +++ b/sys/arch/sparc/dev/if_ie.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ie.c,v 1.23 2002/03/14 01:26:43 millert Exp $ */ +/* $OpenBSD: if_ie.c,v 1.24 2002/04/30 01:12:29 art Exp $ */ /* $NetBSD: if_ie.c,v 1.33 1997/07/29 17:55:38 fair Exp $ */ /*- @@ -669,14 +669,14 @@ ieattach(parent, self, aux) case BUS_OBIO: sc->sc_ih.ih_fun = ieintr; sc->sc_ih.ih_arg = sc; - intr_establish(pri, &sc->sc_ih); + intr_establish(pri, &sc->sc_ih, IPL_NET); break; case BUS_VME16: case BUS_VME32: sc->sc_ih.ih_fun = ieintr; sc->sc_ih.ih_arg = sc; vmeintr_establish(ca->ca_ra.ra_intr[0].int_vec, pri, - &sc->sc_ih); + &sc->sc_ih, IPL_NET); break; #endif /* SUN4 */ } diff --git a/sys/arch/sparc/dev/if_le.c b/sys/arch/sparc/dev/if_le.c index 4cdeffedcce..0ac2c8e093c 100644 --- a/sys/arch/sparc/dev/if_le.c +++ b/sys/arch/sparc/dev/if_le.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_le.c,v 1.19 2002/03/14 01:26:43 millert Exp $ */ +/* $OpenBSD: if_le.c,v 1.20 2002/04/30 01:12:29 art Exp $ */ /* $NetBSD: if_le.c,v 1.50 1997/09/09 20:54:48 pk Exp $ */ /*- @@ -573,7 +573,7 @@ leattach(parent, self, aux) lesc->sc_ih.ih_fun = myleintr; #endif lesc->sc_ih.ih_arg = sc; - intr_establish(pri, &lesc->sc_ih); + intr_establish(pri, &lesc->sc_ih, IPL_NET); /* now initialize DMA */ lehwreset(sc); diff --git a/sys/arch/sparc/dev/isp_sbus.c b/sys/arch/sparc/dev/isp_sbus.c index 671308cdde4..2d79b0f9de0 100644 --- a/sys/arch/sparc/dev/isp_sbus.c +++ b/sys/arch/sparc/dev/isp_sbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: isp_sbus.c,v 1.20 2002/03/14 01:26:43 millert Exp $ */ +/* $OpenBSD: isp_sbus.c,v 1.21 2002/04/30 01:12:29 art Exp $ */ /* * SBus specific probe and attach routines for Qlogic ISP SCSI adapters. * @@ -218,7 +218,7 @@ isp_sbus_attach(struct device *parent, struct device *self, void *aux) /* Establish interrupt channel */ sbc->sbus_ih.ih_fun = (void *) isp_sbus_intr; sbc->sbus_ih.ih_arg = sbc; - intr_establish(sbc->sbus_pri, &sbc->sbus_ih); + intr_establish(sbc->sbus_pri, &sbc->sbus_ih, IPL_BIO); /* * Set up logging levels. diff --git a/sys/arch/sparc/dev/magma.c b/sys/arch/sparc/dev/magma.c index be53eae701f..931711846ad 100644 --- a/sys/arch/sparc/dev/magma.c +++ b/sys/arch/sparc/dev/magma.c @@ -1,4 +1,4 @@ -/* $OpenBSD: magma.c,v 1.12 2002/04/28 03:51:19 art Exp $ */ +/* $OpenBSD: magma.c,v 1.13 2002/04/30 01:12:29 art Exp $ */ /* * magma.c * @@ -465,11 +465,11 @@ void *base; */ sc->ms_hardint.ih_fun = magma_hard; sc->ms_hardint.ih_arg = sc; - intr_establish(ra->ra_intr[0].int_pri, &sc->ms_hardint); + intr_establish(ra->ra_intr[0].int_pri, &sc->ms_hardint, -1); sc->ms_softint.ih_fun = magma_soft; sc->ms_softint.ih_arg = sc; - intr_establish(IPL_TTY, &sc->ms_softint); + intr_establish(IPL_TTY, &sc->ms_softint, IPL_TTY); } /* diff --git a/sys/arch/sparc/dev/obio.c b/sys/arch/sparc/dev/obio.c index bd0f3a46bc5..86cc923ab4c 100644 --- a/sys/arch/sparc/dev/obio.c +++ b/sys/arch/sparc/dev/obio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: obio.c,v 1.12 2002/03/14 01:26:43 millert Exp $ */ +/* $OpenBSD: obio.c,v 1.13 2002/04/30 01:12:29 art Exp $ */ /* $NetBSD: obio.c,v 1.37 1997/07/29 09:58:11 fair Exp $ */ /* @@ -598,9 +598,10 @@ vmeintr(arg) } void -vmeintr_establish(vec, level, ih) +vmeintr_establish(vec, level, ih, ipl_block) int vec, level; struct intrhand *ih; + int ipl_block; { struct intrhand *ihs; @@ -630,7 +631,7 @@ vmeintr_establish(vec, level, ih) bzero(ihs, sizeof *ihs); ihs->ih_fun = vmeintr; ihs->ih_arg = (void *)level; - intr_establish(level, ihs); + intr_establish(level, ihs, ipl_block); } #define getpte(va) lda(va, ASI_PTE) diff --git a/sys/arch/sparc/dev/qe.c b/sys/arch/sparc/dev/qe.c index d216a45a88a..4b9ca2b56da 100644 --- a/sys/arch/sparc/dev/qe.c +++ b/sys/arch/sparc/dev/qe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: qe.c,v 1.21 2002/03/14 01:26:43 millert Exp $ */ +/* $OpenBSD: qe.c,v 1.22 2002/04/30 01:12:29 art Exp $ */ /* * Copyright (c) 1998, 2000 Jason L. Wright. @@ -152,7 +152,7 @@ qeattach(parent, self, aux) sc->sc_ih.ih_fun = qeintr; sc->sc_ih.ih_arg = sc; - intr_establish(pri, &sc->sc_ih); + intr_establish(pri, &sc->sc_ih, IPL_NET); myetheraddr(sc->sc_arpcom.ac_enaddr); diff --git a/sys/arch/sparc/dev/si.c b/sys/arch/sparc/dev/si.c index 7826aca1932..fcef08c2cd0 100644 --- a/sys/arch/sparc/dev/si.c +++ b/sys/arch/sparc/dev/si.c @@ -1,4 +1,4 @@ -/* $OpenBSD: si.c,v 1.16 2002/03/14 03:15:59 millert Exp $ */ +/* $OpenBSD: si.c,v 1.17 2002/04/30 01:12:29 art Exp $ */ /* $NetBSD: si.c,v 1.38 1997/08/27 11:24:20 bouyer Exp $ */ /*- @@ -448,7 +448,7 @@ si_attach(parent, self, args) /* * This will be an "sw" controller. */ - intr_establish(ra->ra_intr[0].int_pri, &sc->sc_ih); + intr_establish(ra->ra_intr[0].int_pri, &sc->sc_ih, IPL_BIO); break; case BUS_VME16: @@ -456,7 +456,7 @@ si_attach(parent, self, args) * This will be an "si" controller. */ vmeintr_establish(ra->ra_intr[0].int_vec, - ra->ra_intr[0].int_pri, &sc->sc_ih); + ra->ra_intr[0].int_pri, &sc->sc_ih, IPL_BIO); sc->sc_adapter_iv_am = VME_SUPV_DATA_24 | (ra->ra_intr[0].int_vec & 0xFF); break; diff --git a/sys/arch/sparc/dev/spif.c b/sys/arch/sparc/dev/spif.c index 9d5dbc018f7..5bde86c4c4a 100644 --- a/sys/arch/sparc/dev/spif.c +++ b/sys/arch/sparc/dev/spif.c @@ -1,4 +1,4 @@ -/* $OpenBSD: spif.c,v 1.11 2002/04/28 03:51:19 art Exp $ */ +/* $OpenBSD: spif.c,v 1.12 2002/04/30 01:12:29 art Exp $ */ /* * Copyright (c) 1999 Jason L. Wright (jason@thought.net) @@ -212,15 +212,15 @@ spifattach(parent, self, aux) sc->sc_ppcih.ih_fun = spifppcintr; sc->sc_ppcih.ih_arg = sc; - intr_establish(ppcpri, &sc->sc_ppcih); + intr_establish(ppcpri, &sc->sc_ppcih, -1); sc->sc_stcih.ih_fun = spifstcintr; sc->sc_stcih.ih_arg = sc; - intr_establish(stcpri, &sc->sc_stcih); + intr_establish(stcpri, &sc->sc_stcih, -1); sc->sc_softih.ih_fun = spifsoftintr; sc->sc_softih.ih_arg = sc; - intr_establish(IPL_TTY, &sc->sc_softih); + intr_establish(IPL_TTY, &sc->sc_softih, IPL_TTY); sbus_establish(&sc->sc_sd, &sc->sc_dev); } diff --git a/sys/arch/sparc/dev/tctrl.c b/sys/arch/sparc/dev/tctrl.c index 108bfff17e3..b6844bdc05d 100644 --- a/sys/arch/sparc/dev/tctrl.c +++ b/sys/arch/sparc/dev/tctrl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tctrl.c,v 1.3 2002/03/14 01:26:43 millert Exp $ */ +/* $OpenBSD: tctrl.c,v 1.4 2002/04/30 01:12:29 art Exp $ */ /* $NetBSD: tctrl.c,v 1.2 1999/08/11 00:46:06 matt Exp $ */ /*- @@ -183,7 +183,7 @@ tctrl_attach(parent, self, aux) sc->sc_ih.ih_fun = tctrl_intr; sc->sc_ih.ih_arg = sc; - intr_establish(pri, &sc->sc_ih); + intr_establish(pri, &sc->sc_ih, -1); evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt); /* See what the external status is diff --git a/sys/arch/sparc/dev/xd.c b/sys/arch/sparc/dev/xd.c index 76a433b9149..9648f63ea3d 100644 --- a/sys/arch/sparc/dev/xd.c +++ b/sys/arch/sparc/dev/xd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xd.c,v 1.21 2002/03/14 01:26:43 millert Exp $ */ +/* $OpenBSD: xd.c,v 1.22 2002/04/30 01:12:29 art Exp $ */ /* $NetBSD: xd.c,v 1.37 1997/07/29 09:58:16 fair Exp $ */ /* @@ -488,7 +488,7 @@ xdcattach(parent, self, aux) xdc->sc_ih.ih_fun = xdcintr; xdc->sc_ih.ih_arg = xdc; vmeintr_establish(ca->ca_ra.ra_intr[0].int_vec, - ca->ca_ra.ra_intr[0].int_pri, &xdc->sc_ih); + ca->ca_ra.ra_intr[0].int_pri, &xdc->sc_ih, IPL_BIO); evcnt_attach(&xdc->sc_dev, "intr", &xdc->sc_intrcnt); diff --git a/sys/arch/sparc/dev/xy.c b/sys/arch/sparc/dev/xy.c index 05c948e501f..169fe362d8c 100644 --- a/sys/arch/sparc/dev/xy.c +++ b/sys/arch/sparc/dev/xy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xy.c,v 1.18 2002/03/14 01:26:43 millert Exp $ */ +/* $OpenBSD: xy.c,v 1.19 2002/04/30 01:12:29 art Exp $ */ /* $NetBSD: xy.c,v 1.26 1997/07/19 21:43:56 pk Exp $ */ /* @@ -431,7 +431,7 @@ xycattach(parent, self, aux) xyc->sc_ih.ih_fun = xycintr; xyc->sc_ih.ih_arg = xyc; vmeintr_establish(ca->ca_ra.ra_intr[0].int_vec, - ca->ca_ra.ra_intr[0].int_pri, &xyc->sc_ih); + ca->ca_ra.ra_intr[0].int_pri, &xyc->sc_ih, IPL_BIO); evcnt_attach(&xyc->sc_dev, "intr", &xyc->sc_intrcnt); diff --git a/sys/arch/sparc/dev/zs.c b/sys/arch/sparc/dev/zs.c index d535aa8ae39..939d920573a 100644 --- a/sys/arch/sparc/dev/zs.c +++ b/sys/arch/sparc/dev/zs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: zs.c,v 1.34 2002/04/28 03:51:19 art Exp $ */ +/* $OpenBSD: zs.c,v 1.35 2002/04/30 01:12:29 art Exp $ */ /* $NetBSD: zs.c,v 1.49 1997/08/31 21:26:37 pk Exp $ */ /* @@ -296,8 +296,8 @@ zsattach(parent, dev, aux) if (!didintr) { didintr = 1; prevpri = pri; - intr_establish(pri, &levelhard); - intr_establish(IPL_TTY, &levelsoft); + intr_establish(pri, &levelhard, IPL_ZS); + intr_establish(IPL_TTY, &levelsoft, IPL_TTY); } else if (pri != prevpri) panic("broken zs interrupt scheme"); sc = (struct zs_softc *)dev; diff --git a/sys/arch/sparc/include/cpu.h b/sys/arch/sparc/include/cpu.h index 7400cc6e4c0..97778d3740e 100644 --- a/sys/arch/sparc/include/cpu.h +++ b/sys/arch/sparc/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.13 2002/03/14 03:16:00 millert Exp $ */ +/* $OpenBSD: cpu.h,v 1.14 2002/04/30 01:12:28 art Exp $ */ /* $NetBSD: cpu.h,v 1.24 1997/03/15 22:25:15 pk Exp $ */ /* @@ -153,15 +153,18 @@ extern int foundfpu; /* true => we have an FPU */ * ``not me'' or 1 (``I took care of it''). intr_establish() inserts a * handler into the list. The handler is called with its (single) * argument, or with a pointer to a clockframe if ih_arg is NULL. + * ih_ipl specifies the interrupt level that should be blocked when + * executing this handler. */ struct intrhand { int (*ih_fun)(void *); void *ih_arg; + int ih_ipl; struct intrhand *ih_next; }; extern struct intrhand *intrhand[15]; -void intr_establish(int level, struct intrhand *); -void vmeintr_establish(int vec, int level, struct intrhand *); +void intr_establish(int level, struct intrhand *, int); +void vmeintr_establish(int vec, int level, struct intrhand *, int); /* * intr_fasttrap() is a lot like intr_establish, but is used for ``fast'' diff --git a/sys/arch/sparc/sparc/genassym.cf b/sys/arch/sparc/sparc/genassym.cf index 769897f640a..582278791a7 100644 --- a/sys/arch/sparc/sparc/genassym.cf +++ b/sys/arch/sparc/sparc/genassym.cf @@ -1,4 +1,4 @@ -# $OpenBSD: genassym.cf,v 1.11 2002/04/28 21:48:08 art Exp $ +# $OpenBSD: genassym.cf,v 1.12 2002/04/30 01:12:28 art Exp $ # $NetBSD: genassym.cf,v 1.2 1997/06/28 19:59:04 pk Exp $ # @@ -165,6 +165,7 @@ define IE_REG_PTE_PG (PG_V | PG_W | PG_S | PG_NC | PG_OBIO) struct intrhand member ih_fun member ih_arg +member ih_ipl member ih_next ifdef notyet diff --git a/sys/arch/sparc/sparc/intr.c b/sys/arch/sparc/sparc/intr.c index 8d53eab0140..24e92b62f38 100644 --- a/sys/arch/sparc/sparc/intr.c +++ b/sys/arch/sparc/sparc/intr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.c,v 1.18 2002/03/14 01:26:44 millert Exp $ */ +/* $OpenBSD: intr.c,v 1.19 2002/04/30 01:12:28 art Exp $ */ /* $NetBSD: intr.c,v 1.20 1997/07/29 09:42:03 fair Exp $ */ /* @@ -104,8 +104,8 @@ strayintr(fp) } } -static struct intrhand level10 = { clockintr }; -static struct intrhand level14 = { statintr }; +static struct intrhand level10 = { clockintr, NULL, (IPL_CLOCK << 8) }; +static struct intrhand level14 = { statintr, NULL, (14 << 8) /* XXX - IPL_STATCLOCK */ }; union sir sir; /* * Level 1 software interrupt (could also be Sbus level 1 interrupt). @@ -210,7 +210,7 @@ nmi_hard() } #endif -static struct intrhand level01 = { soft01intr }; +static struct intrhand level01 = { soft01intr, NULL, (IPL_SOFTINT << 8) }; /* * Level 15 interrupts are special, and not vectored here. @@ -246,9 +246,10 @@ extern int sparc_interrupt44c[]; * This is not possible if it has been taken away as a fast vector. */ void -intr_establish(level, ih) +intr_establish(level, ih, ipl_block) int level; struct intrhand *ih; + int ipl_block; { struct intrhand **p, *q; #ifdef DIAGNOSTIC @@ -257,6 +258,29 @@ intr_establish(level, ih) #endif int s; + if (ipl_block == -1) + ipl_block = level; + +#ifdef DIAGNOSTIC + /* + * If the level we're supposed to block is lower than this interrupts + * level someone is doing something very wrong. Most likely it + * means that some IPL_ constant in machine/psl.h is preconfigured too + * low. + */ + if (ipl_block < level) + panic("intr_establish: level (%d) > block (%d)", level, + ipl_block); + if (ipl_block > 15) + panic("intr_establish: strange block level: %d", ipl_block); +#endif + + /* + * We store the ipl pre-shifted so that we can avoid one instruction + * in the interrupt handlers. + */ + ih->ih_ipl = (ipl_block << 8); + s = splhigh(); if (fastvec & (1 << level)) panic("intr_establish: level %d interrupt tied to fast vector", diff --git a/sys/arch/sparc/sparc/locore.s b/sys/arch/sparc/sparc/locore.s index a1967d0e74a..899b1bfd48b 100644 --- a/sys/arch/sparc/sparc/locore.s +++ b/sys/arch/sparc/sparc/locore.s @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.s,v 1.49 2002/04/28 21:48:08 art Exp $ */ +/* $OpenBSD: locore.s,v 1.50 2002/04/30 01:12:28 art Exp $ */ /* $NetBSD: locore.s,v 1.73 1997/09/13 20:36:48 pk Exp $ */ /* @@ -2364,8 +2364,12 @@ softintr_common: b 3f st %fp, [%sp + CCFSZ + 16] -1: ld [%l4 + IH_FUN], %o1 +1: rd %psr, %o1 + ld [%l4 + IH_IPL], %o0 + and %o1, ~PSR_PIL, %o1 + wr %o1, %o0, %psr ld [%l4 + IH_ARG], %o0 + ld [%l4 + IH_FUN], %o1 tst %o0 bz,a 2f add %sp, CCFSZ, %o0 @@ -2433,8 +2437,12 @@ _sparc_interrupt_common: b 3f st %fp, [%sp + CCFSZ + 16] -1: ld [%l4 + IH_FUN], %o1 +1: rd %psr, %o1 + ld [%l4 + IH_IPL], %o0 + and %o1, ~PSR_PIL, %o1 + wr %o1, %o0, %psr ld [%l4 + IH_ARG], %o0 + ld [%l4 + IH_FUN], %o1 tst %o0 bz,a 2f add %sp, CCFSZ, %o0 |