diff options
author | jhb <jhb@FreeBSD.org> | 2001-12-20 23:48:31 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2001-12-20 23:48:31 +0000 |
commit | 2463f40fc340e69b97e1ba3f1a7db47384b50a83 (patch) | |
tree | dec76d77f99795635c90df0631ffc2beb333b91b /sys/alpha | |
parent | 7a0109b5c0a87d4cff83c1923789cf9c5b38126a (diff) | |
download | FreeBSD-src-2463f40fc340e69b97e1ba3f1a7db47384b50a83.zip FreeBSD-src-2463f40fc340e69b97e1ba3f1a7db47384b50a83.tar.gz |
Introduce a standard name for the lock protecting an interrupt controller
and it's associated state variables: icu_lock with the name "icu". This
renames the imen_mtx for x86 SMP, but also uses the lock to protect
access to the 8259 PIC on x86 UP. This also adds an appropriate lock to
the various Alpha chipsets which fixes problems with Alpha SMP machines
dropping interrupts with an SMP kernel.
Diffstat (limited to 'sys/alpha')
-rw-r--r-- | sys/alpha/alpha/machdep.c | 2 | ||||
-rw-r--r-- | sys/alpha/include/intr.h | 2 | ||||
-rw-r--r-- | sys/alpha/isa/isa.c | 29 | ||||
-rw-r--r-- | sys/alpha/mcbus/mcpcia.c | 16 | ||||
-rw-r--r-- | sys/alpha/pci/apecs.c | 18 | ||||
-rw-r--r-- | sys/alpha/pci/cia.c | 18 | ||||
-rw-r--r-- | sys/alpha/pci/t2.c | 12 | ||||
-rw-r--r-- | sys/alpha/pci/tsunami.c | 17 | ||||
-rw-r--r-- | sys/alpha/tlsb/dwlpx.c | 9 |
9 files changed, 101 insertions, 22 deletions
diff --git a/sys/alpha/alpha/machdep.c b/sys/alpha/alpha/machdep.c index a6f181c..6680425 100644 --- a/sys/alpha/alpha/machdep.c +++ b/sys/alpha/alpha/machdep.c @@ -155,6 +155,7 @@ struct bootinfo_kernel bootinfo; struct mtx sched_lock; struct mtx Giant; +struct mtx icu_lock; struct user *proc0uarea; vm_offset_t proc0kstack; @@ -955,6 +956,7 @@ alpha_init(pfn, ptb, bim, bip, biv) mtx_init(&sched_lock, "sched lock", MTX_SPIN | MTX_RECURSE); mtx_init(&proc0.p_mtx, "process lock", MTX_DEF); mtx_init(&clock_lock, "clk", MTX_SPIN | MTX_RECURSE); + mtx_init(&icu_lock, "icu", MTX_SPIN); mtx_lock(&Giant); /* diff --git a/sys/alpha/include/intr.h b/sys/alpha/include/intr.h index 6ff2271..ea71e3f 100644 --- a/sys/alpha/include/intr.h +++ b/sys/alpha/include/intr.h @@ -29,6 +29,8 @@ #ifndef _MACHINE_INTR_H_ #define _MACHINE_INTR_H_ +extern struct mtx icu_lock; + int alpha_setup_intr(const char *name, int vector, driver_intr_t handler, void *arg, enum intr_type flags, void **cookiep, volatile long *cntp, void (*disable)(int), void (*enable)(int)); diff --git a/sys/alpha/isa/isa.c b/sys/alpha/isa/isa.c index 95c7d58..694f4c1 100644 --- a/sys/alpha/isa/isa.c +++ b/sys/alpha/isa/isa.c @@ -29,7 +29,9 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> +#include <sys/lock.h> #include <sys/module.h> +#include <sys/mutex.h> #include <sys/bus.h> #include <machine/bus.h> #include <sys/malloc.h> @@ -52,23 +54,21 @@ static struct rman isa_drq_rman; static void isa_intr_enable(int irq) { - int s = splhigh(); + if (irq < 8) outb(IO_ICU1+1, inb(IO_ICU1+1) & ~(1 << irq)); else outb(IO_ICU2+1, inb(IO_ICU2+1) & ~(1 << (irq - 8))); - splx(s); } static void isa_intr_disable(int irq) { - int s = splhigh(); + if (irq < 8) outb(IO_ICU1+1, inb(IO_ICU1+1) | (1 << irq)); else outb(IO_ICU2+1, inb(IO_ICU2+1) | (1 << (irq - 8))); - splx(s); } intrmask_t @@ -77,8 +77,10 @@ isa_irq_pending(void) u_char irr1; u_char irr2; + mtx_lock_spin(&icu_lock); irr1 = inb(IO_ICU1); irr2 = inb(IO_ICU2); + mtx_unlock_spin(&icu_lock); return ((irr2 << 8) | irr1); } @@ -88,8 +90,10 @@ isa_irq_mask(void) u_char irr1; u_char irr2; + mtx_lock_spin(&icu_lock); irr1 = inb(IO_ICU1+1); irr2 = inb(IO_ICU2+1); + mtx_unlock_spin(&icu_lock); return ((irr2 << 8) | irr1); } @@ -289,9 +293,11 @@ isa_handle_fast_intr(void *arg) ii->intr(ii->arg); + mtx_lock_spin(&icu_lock); if (irq > 7) outb(IO_ICU2, 0x20 | (irq & 7)); outb(IO_ICU1, 0x20 | (irq > 7 ? 2 : irq)); + mtx_unlock_spin(&icu_lock); } static void @@ -311,18 +317,24 @@ isa_disable_intr(int vector) { int irq = (vector - 0x800) >> 4; + mtx_lock_spin(&icu_lock); if (irq > 7) outb(IO_ICU2, 0x20 | (irq & 7)); outb(IO_ICU1, 0x20 | (irq > 7 ? 2 : irq)); isa_intr_disable(irq); + mtx_unlock_spin(&icu_lock); } static void isa_enable_intr(int vector) { - int irq = (vector - 0x800) >> 4; + int irq; + + irq = (vector - 0x800) >> 4; + mtx_lock_spin(&icu_lock); isa_intr_enable(irq); + mtx_unlock_spin(&icu_lock); } @@ -363,7 +375,9 @@ isa_setup_intr(device_t dev, device_t child, free(ii, M_DEVBUF); return error; } + mtx_lock_spin(&icu_lock); isa_intr_enable(irq->r_start); + mtx_unlock_spin(&icu_lock); *cookiep = ii; @@ -380,13 +394,16 @@ isa_teardown_intr(device_t dev, device_t child, { struct isa_intr *ii = cookie; + mtx_lock_spin(&icu_lock); + isa_intr_disable(irq->r_start); + mtx_unlock_spin(&icu_lock); + if (platform.isa_teardown_intr) { platform.isa_teardown_intr(dev, child, irq, cookie); return 0; } alpha_teardown_intr(ii->ih); - isa_intr_disable(irq->r_start); return 0; } diff --git a/sys/alpha/mcbus/mcpcia.c b/sys/alpha/mcbus/mcpcia.c index ae34e76..82be484 100644 --- a/sys/alpha/mcbus/mcpcia.c +++ b/sys/alpha/mcbus/mcpcia.c @@ -29,8 +29,10 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/module.h> +#include <sys/lock.h> #include <sys/malloc.h> +#include <sys/module.h> +#include <sys/mutex.h> #include <sys/bus.h> #include <machine/bus.h> #include <machine/md_var.h> @@ -247,6 +249,7 @@ mcpcia_attach(device_t dev) static void mcpcia_enable_intr(struct mcpcia_softc *sc, int irq) { + REGVAL(MCPCIA_INT_MASK0(sc)) |= (1 << irq); alpha_mb(); } @@ -254,6 +257,7 @@ mcpcia_enable_intr(struct mcpcia_softc *sc, int irq) static void mcpcia_disable_intr(struct mcpcia_softc *sc, int irq) { + /* * We need to write to INT_REQ as well as INT_MASK0 in case we * are trying to mask an interrupt which is already @@ -262,7 +266,7 @@ mcpcia_disable_intr(struct mcpcia_softc *sc, int irq) */ REGVAL(MCPCIA_INT_MASK0(sc)) &= ~(1 << irq); REGVAL(MCPCIA_INT_REQ(sc)) = (1 << irq); - alpha_mb(); + alpha_mb(); } static void @@ -302,7 +306,9 @@ mcpcia_disable_intr_vec(int vector) if (sc == NULL) { panic("couldn't find MCPCIA softc for vector 0x%x", vector); } + mtx_lock_spin(&icu_lock); mcpcia_disable_intr(sc, irq); + mtx_unlock_spin(&icu_lock); } static void @@ -342,7 +348,9 @@ mcpcia_enable_intr_vec(int vector) if (sc == NULL) { panic("couldn't find MCPCIA softc for vector 0x%x", vector); } + mtx_lock_spin(&icu_lock); mcpcia_enable_intr(sc, irq); + mtx_unlock_spin(&icu_lock); } static int @@ -405,7 +413,9 @@ mcpcia_setup_intr(device_t dev, device_t child, struct resource *ir, int flags, mcpcia_disable_intr_vec, mcpcia_enable_intr_vec); if (error) return error; + mtx_lock_spin(&icu_lock); mcpcia_enable_intr(sc, irq); + mtx_unlock_spin(&icu_lock); device_printf(child, "interrupting at IRQ 0x%x int%c (vec 0x%x)\n", irq, intpin - 1 + 'A' , h); return (0); @@ -437,7 +447,9 @@ mcpcia_teardown_intr(device_t dev, device_t child, struct resource *i, void *c) } else { return (ENXIO); } + mtx_lock_spin(&icu_lock); mcpcia_disable_intr(sc, irq); + mtx_unlock_spin(&icu_lock); alpha_teardown_intr(c); return (rman_deactivate_resource(i)); } diff --git a/sys/alpha/pci/apecs.c b/sys/alpha/pci/apecs.c index ebe350b..c74e940 100644 --- a/sys/alpha/pci/apecs.c +++ b/sys/alpha/pci/apecs.c @@ -58,8 +58,10 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/module.h> +#include <sys/lock.h> #include <sys/malloc.h> +#include <sys/module.h> +#include <sys/mutex.h> #include <sys/bus.h> #include <machine/bus.h> #include <sys/proc.h> @@ -304,15 +306,23 @@ apecs_attach(device_t dev) static void apecs_disable_intr(int vector) { - int irq = (vector - 0x900) >> 4; + int irq; + + irq = (vector - 0x900) >> 4; + mtx_lock_spin(&icu_lock); platform.pci_intr_disable(irq); + mtx_unlock_spin(&icu_lock); } static void apecs_enable_intr(int vector) { - int irq = (vector - 0x900) >> 4; + int irq; + + irq = (vector - 0x900) >> 4; + mtx_lock_spin(&icu_lock); platform.pci_intr_enable(irq); + mtx_unlock_spin(&icu_lock); } static int @@ -342,7 +352,9 @@ apecs_setup_intr(device_t dev, device_t child, return error; /* Enable PCI interrupt */ + mtx_lock_spin(&icu_lock); platform.pci_intr_enable(irq->r_start); + mtx_unlock_spin(&icu_lock); device_printf(child, "interrupting at APECS irq %d\n", (int) irq->r_start); diff --git a/sys/alpha/pci/cia.c b/sys/alpha/pci/cia.c index 09436e3..40f205c 100644 --- a/sys/alpha/pci/cia.c +++ b/sys/alpha/pci/cia.c @@ -94,8 +94,10 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/module.h> +#include <sys/lock.h> #include <sys/malloc.h> +#include <sys/module.h> +#include <sys/mutex.h> #include <sys/bus.h> #include <machine/bus.h> #include <sys/proc.h> @@ -513,15 +515,23 @@ cia_attach(device_t dev) static void cia_disable_intr(int vector) { - int irq = (vector - 0x900) >> 4; + int irq; + + irq = (vector - 0x900) >> 4; + mtx_lock_spin(&icu_lock); platform.pci_intr_disable(irq); + mtx_unlock_spin(&icu_lock); } static void cia_enable_intr(int vector) { - int irq = (vector - 0x900) >> 4; + int irq; + + irq = (vector - 0x900) >> 4; + mtx_lock_spin(&icu_lock); platform.pci_intr_enable(irq); + mtx_unlock_spin(&icu_lock); } static int @@ -544,7 +554,9 @@ cia_setup_intr(device_t dev, device_t child, return error; /* Enable PCI interrupt */ + mtx_lock_spin(&icu_lock); platform.pci_intr_enable(irq->r_start); + mtx_unlock_spin(&icu_lock); device_printf(child, "interrupting at CIA irq %d\n", (int) irq->r_start); diff --git a/sys/alpha/pci/t2.c b/sys/alpha/pci/t2.c index d9d0b9d..3dcfe35 100644 --- a/sys/alpha/pci/t2.c +++ b/sys/alpha/pci/t2.c @@ -55,8 +55,10 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/module.h> +#include <sys/lock.h> #include <sys/malloc.h> +#include <sys/module.h> +#include <sys/mutex.h> #include <sys/bus.h> #include <machine/bus.h> #include <sys/proc.h> @@ -460,6 +462,7 @@ t2_enable_vec(int vector) hose = (vector >= 0xC00); irq = (vector - 0x800) >> 4; + mtx_lock_spin(&icu_lock); if (pci_int_type[hose]) { /* Write the air register on the T3/T4 with the @@ -481,6 +484,7 @@ t2_enable_vec(int vector) /* Old style 8259 (Gack!!!) interrupts */ t2_8259_enable_mask(irq); } + mtx_unlock_spin(&icu_lock); } static void @@ -492,6 +496,7 @@ t2_disable_vec(int vector) hose = (vector >= 0xC00); irq = (vector - 0x800) >> 4; + mtx_lock_spin(&icu_lock); if (pci_int_type[hose]) { /* Write the air register on the T3/T4 wioth the @@ -515,6 +520,7 @@ t2_disable_vec(int vector) /* Old style 8259 (Gack!!!) interrupts */ t2_8259_disable_mask(irq); } + mtx_unlock_spin(&icu_lock); } @@ -590,12 +596,14 @@ t2_teardown_intr(device_t dev, device_t child, t2_shadow_mask |= (1UL << mask); + mtx_lock_spin(&icu_lock); if (mask <= 7) outb(SLAVE0_ICU, t2_shadow_mask); else if (mask <= 15) outb(SLAVE1_ICU, t2_shadow_mask >> 8); else outb(SLAVE2_ICU, t2_shadow_mask >> 16); + mtx_unlock_spin(&icu_lock); alpha_teardown_intr(cookie); return rman_deactivate_resource(irq); @@ -607,7 +615,9 @@ static void t2_dispatch_intr(void *frame, unsigned long vector) { alpha_dispatch_intr(frame, vector); + mtx_lock_spin(&icu_lock); t2_eoi(vector); + mtx_unlock_spin(&icu_lock); } static void diff --git a/sys/alpha/pci/tsunami.c b/sys/alpha/pci/tsunami.c index 1ca0803..3ca127b 100644 --- a/sys/alpha/pci/tsunami.c +++ b/sys/alpha/pci/tsunami.c @@ -31,7 +31,9 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> +#include <sys/lock.h> #include <sys/module.h> +#include <sys/mutex.h> #include <sys/bus.h> #include <machine/bus.h> #include <sys/proc.h> @@ -305,15 +307,23 @@ tsunami_attach(device_t dev) static void tsunami_disable_intr_vec(int vector) { - int irq = (vector - 0x900) >> 4; + int irq; + + irq = (vector - 0x900) >> 4; + mtx_lock_spin(&icu_lock); platform.pci_intr_disable(irq); + mtx_unlock_spin(&icu_lock); } static void tsunami_enable_intr_vec(int vector) { - int irq = (vector - 0x900) >> 4; + int irq; + + irq = (vector - 0x900) >> 4; + mtx_lock_spin(&icu_lock); platform.pci_intr_enable(irq); + mtx_unlock_spin(&icu_lock); } static int @@ -335,7 +345,9 @@ tsunami_setup_intr(device_t dev, device_t child, return error; /* Enable PCI interrupt */ + mtx_lock_spin(&icu_lock); platform.pci_intr_enable(irq->r_start); + mtx_unlock_spin(&icu_lock); device_printf(child, "interrupting at TSUNAMI irq %d\n", (int) irq->r_start); @@ -391,7 +403,6 @@ tsunami_intr_disable(int irq) saved_mask = *mask; alpha_mb(); alpha_mb(); - } diff --git a/sys/alpha/tlsb/dwlpx.c b/sys/alpha/tlsb/dwlpx.c index 2f778ef..939fd69 100644 --- a/sys/alpha/tlsb/dwlpx.c +++ b/sys/alpha/tlsb/dwlpx.c @@ -63,7 +63,9 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> +#include <sys/lock.h> #include <sys/module.h> +#include <sys/mutex.h> #include <sys/bus.h> #include <machine/bus.h> #include <machine/md_var.h> @@ -344,7 +346,7 @@ dwlpx_enadis_intr(int vector, int intpin, int onoff) { unsigned long paddr; u_int32_t val; - int device, ionode, hose, hpc, s; + int device, ionode, hose, hpc; ionode = DWLPX_MVEC_IONODE(vector); hose = DWLPX_MVEC_HOSE(vector); @@ -363,16 +365,15 @@ dwlpx_enadis_intr(int vector, int intpin, int onoff) device -= 8; } intpin <<= (device << 2); + mtx_lock_spin(&icu_lock); val = imaskcache[ionode][hose][hpc]; if (onoff) val |= intpin; else val &= ~intpin; imaskcache[ionode][hose][hpc] = val; - s = splhigh(); REGVAL(PCIA_IMASK(hpc) + paddr) = val; - alpha_mb(); - splx(s); + mtx_unlock_spin(&icu_lock); } static int |