summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/alpha/alpha/machdep.c2
-rw-r--r--sys/alpha/include/intr.h2
-rw-r--r--sys/alpha/isa/isa.c29
-rw-r--r--sys/alpha/mcbus/mcpcia.c16
-rw-r--r--sys/alpha/pci/apecs.c18
-rw-r--r--sys/alpha/pci/cia.c18
-rw-r--r--sys/alpha/pci/t2.c12
-rw-r--r--sys/alpha/pci/tsunami.c17
-rw-r--r--sys/alpha/tlsb/dwlpx.c9
-rw-r--r--sys/amd64/amd64/apic_vector.S10
-rw-r--r--sys/amd64/amd64/fpu.c3
-rw-r--r--sys/amd64/amd64/machdep.c5
-rw-r--r--sys/amd64/amd64/mp_machdep.c3
-rw-r--r--sys/amd64/amd64/mptable.c3
-rw-r--r--sys/amd64/amd64/tsc.c10
-rw-r--r--sys/amd64/include/apicreg.h24
-rw-r--r--sys/amd64/include/mptable.h3
-rw-r--r--sys/amd64/isa/clock.c10
-rw-r--r--sys/amd64/isa/intr_machdep.c27
-rw-r--r--sys/amd64/isa/intr_machdep.h11
-rw-r--r--sys/amd64/isa/nmi.c27
-rw-r--r--sys/amd64/isa/npx.c3
-rw-r--r--sys/amd64/isa/vector.S1
-rw-r--r--sys/amd64/isa/vector.s1
-rw-r--r--sys/i386/i386/apic_vector.s10
-rw-r--r--sys/i386/i386/machdep.c5
-rw-r--r--sys/i386/i386/mp_machdep.c3
-rw-r--r--sys/i386/i386/mpapic.c8
-rw-r--r--sys/i386/i386/mptable.c3
-rw-r--r--sys/i386/i386/tsc.c10
-rw-r--r--sys/i386/include/apic.h24
-rw-r--r--sys/i386/include/apicreg.h24
-rw-r--r--sys/i386/include/mptable.h3
-rw-r--r--sys/i386/isa/apic_ipl.s24
-rw-r--r--sys/i386/isa/apic_vector.s10
-rw-r--r--sys/i386/isa/clock.c10
-rw-r--r--sys/i386/isa/intr_machdep.c27
-rw-r--r--sys/i386/isa/intr_machdep.h11
-rw-r--r--sys/i386/isa/nmi.c27
-rw-r--r--sys/i386/isa/npx.c3
-rw-r--r--sys/i386/isa/vector.s1
-rw-r--r--sys/isa/atrtc.c10
-rw-r--r--sys/kern/subr_witness.c4
43 files changed, 270 insertions, 211 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
diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S
index 3d7a687..6147b31 100644
--- a/sys/amd64/amd64/apic_vector.S
+++ b/sys/amd64/amd64/apic_vector.S
@@ -7,8 +7,6 @@
#include <machine/apic.h>
#include <machine/smp.h>
-#include "i386/isa/intr_machdep.h"
-
/* convert an absolute IRQ# into a bitmask */
#define IRQ_BIT(irq_num) (1 << (irq_num))
@@ -67,7 +65,7 @@ IDTVEC(vec_name) ; \
#define REDIRIDX(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 12
#define MASK_IRQ(irq_num) \
- IMASK_LOCK ; /* into critical reg */ \
+ ICU_LOCK ; /* into critical reg */ \
testl $IRQ_BIT(irq_num), apic_imen ; \
jne 7f ; /* masked, don't mask */ \
orl $IRQ_BIT(irq_num), apic_imen ; /* set the mask bit */ \
@@ -78,7 +76,7 @@ IDTVEC(vec_name) ; \
orl $IOART_INTMASK, %eax ; /* set the mask */ \
movl %eax, IOAPIC_WINDOW(%ecx) ; /* new value */ \
7: ; /* already masked */ \
- IMASK_UNLOCK
+ ICU_UNLOCK
/*
* Test to see whether we are handling an edge or level triggered INT.
* Level-triggered INTs must still be masked as we don't clear the source,
@@ -113,7 +111,7 @@ IDTVEC(vec_name) ; \
* Test to see if the source is currently masked, clear if so.
*/
#define UNMASK_IRQ(irq_num) \
- IMASK_LOCK ; /* into critical reg */ \
+ ICU_LOCK ; /* into critical reg */ \
testl $IRQ_BIT(irq_num), _apic_imen ; \
je 7f ; /* bit clear, not masked */ \
andl $~IRQ_BIT(irq_num), _apic_imen ;/* clear mask bit */ \
@@ -124,7 +122,7 @@ IDTVEC(vec_name) ; \
andl $~IOART_INTMASK, %eax ; /* clear the mask */ \
movl %eax, IOAPIC_WINDOW(%ecx) ; /* new value */ \
7: ; /* already unmasked */ \
- IMASK_UNLOCK
+ ICU_UNLOCK
/*
* Slow, threaded interrupts.
diff --git a/sys/amd64/amd64/fpu.c b/sys/amd64/amd64/fpu.c
index 34a822a..5d44aaa 100644
--- a/sys/amd64/amd64/fpu.c
+++ b/sys/amd64/amd64/fpu.c
@@ -82,6 +82,7 @@
#include <i386/isa/isa.h>
#endif
#endif
+#include <i386/isa/intr_machdep.h>
#include <isa/isavar.h>
/*
@@ -425,7 +426,9 @@ no_irq13:
* XXX hack around brokenness of bus_teardown_intr(). If we left the
* irq active then we would get it instead of exception 16.
*/
+ mtx_lock_spin(&icu_lock);
INTRDIS(1 << irq_num);
+ mtx_unlock_spin(&icu_lock);
bus_release_resource(dev, SYS_RES_IRQ, irq_rid, irq_res);
bus_release_resource(dev, SYS_RES_IOPORT, ioport_rid, ioport_res);
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index c2ef5dc..349a140 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -211,6 +211,7 @@ static struct pcpu __pcpu;
struct mtx sched_lock;
struct mtx Giant;
+struct mtx icu_lock;
static void
cpu_startup(dummy)
@@ -1744,9 +1745,7 @@ init386(first)
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);
-#ifdef SMP
- mtx_init(&imen_mtx, "imen", MTX_SPIN);
-#endif
+ mtx_init(&icu_lock, "icu", MTX_SPIN);
mtx_lock(&Giant);
/* make ldt memory segments */
diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c
index e8da25b..1feb66a 100644
--- a/sys/amd64/amd64/mp_machdep.c
+++ b/sys/amd64/amd64/mp_machdep.c
@@ -320,9 +320,6 @@ static void release_aps(void *dummy);
* initialize all the SMP locks
*/
-/* critical region around IO APIC, apic_imen */
-struct mtx imen_mtx;
-
/* lock region used by kernel profiling */
int mcount_lock;
diff --git a/sys/amd64/amd64/mptable.c b/sys/amd64/amd64/mptable.c
index e8da25b..1feb66a 100644
--- a/sys/amd64/amd64/mptable.c
+++ b/sys/amd64/amd64/mptable.c
@@ -320,9 +320,6 @@ static void release_aps(void *dummy);
* initialize all the SMP locks
*/
-/* critical region around IO APIC, apic_imen */
-struct mtx imen_mtx;
-
/* lock region used by kernel profiling */
int mcount_lock;
diff --git a/sys/amd64/amd64/tsc.c b/sys/amd64/amd64/tsc.c
index a7aaea0..a39f773 100644
--- a/sys/amd64/amd64/tsc.c
+++ b/sys/amd64/amd64/tsc.c
@@ -1026,7 +1026,9 @@ cpu_initclocks()
inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL,
INTR_TYPE_CLK | INTR_FAST, &clkdesc);
+ mtx_lock_spin(&icu_lock);
INTREN(1 << apic_8254_intr);
+ mtx_unlock_spin(&icu_lock);
#else /* APIC_IO */
@@ -1037,7 +1039,9 @@ cpu_initclocks()
*/
inthand_add("clk", 0, (driver_intr_t *)clkintr, NULL,
INTR_TYPE_CLK | INTR_FAST, NULL);
+ mtx_lock_spin(&icu_lock);
INTREN(IRQ0);
+ mtx_unlock_spin(&icu_lock);
#endif /* APIC_IO */
@@ -1060,11 +1064,13 @@ cpu_initclocks()
inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL,
INTR_TYPE_CLK | INTR_FAST, NULL);
+ mtx_lock_spin(&icu_lock);
#ifdef APIC_IO
INTREN(APIC_IRQ8);
#else
INTREN(IRQ8);
#endif /* APIC_IO */
+ mtx_unlock_spin(&icu_lock);
writertc(RTC_STATUSB, rtc_statusb);
@@ -1081,7 +1087,9 @@ cpu_initclocks()
* on the IO APIC.
* Workaround: Limited variant of mixed mode.
*/
+ mtx_lock_spin(&icu_lock);
INTRDIS(1 << apic_8254_intr);
+ mtx_unlock_spin(&icu_lock);
inthand_remove(clkdesc);
printf("APIC_IO: Broken MP table detected: "
"8254 is not connected to "
@@ -1104,7 +1112,9 @@ cpu_initclocks()
inthand_add("clk", apic_8254_intr,
(driver_intr_t *)clkintr, NULL,
INTR_TYPE_CLK | INTR_FAST, NULL);
+ mtx_lock_spin(&icu_lock);
INTREN(1 << apic_8254_intr);
+ mtx_unlock_spin(&icu_lock);
}
}
diff --git a/sys/amd64/include/apicreg.h b/sys/amd64/include/apicreg.h
index 6345ce7..70b8011 100644
--- a/sys/amd64/include/apicreg.h
+++ b/sys/amd64/include/apicreg.h
@@ -458,28 +458,4 @@ typedef struct IOAPIC ioapic_t;
#define IOART_INTVEC 0x000000ff /* R/W: INTerrupt vector field */
-#ifdef LOCORE
-
-#ifdef SMP
-
-/*
- * Protects the IO APIC and apic_imen as a critical region.
- */
-#define IMASK_LOCK MTX_LOCK_SPIN(imen_mtx, 0)
-#define IMASK_UNLOCK MTX_UNLOCK_SPIN(imen_mtx)
-
-#else /* SMP */
-
-#define IMASK_LOCK /* NOP */
-#define IMASK_UNLOCK /* NOP */
-
-#endif /* SMP */
-
-#else /* LOCORE */
-
-/* global data in mp_machdep.c */
-extern struct mtx imen_mtx;
-
-#endif /* LOCORE */
-
#endif /* _MACHINE_APIC_H_ */
diff --git a/sys/amd64/include/mptable.h b/sys/amd64/include/mptable.h
index e8da25b..1feb66a 100644
--- a/sys/amd64/include/mptable.h
+++ b/sys/amd64/include/mptable.h
@@ -320,9 +320,6 @@ static void release_aps(void *dummy);
* initialize all the SMP locks
*/
-/* critical region around IO APIC, apic_imen */
-struct mtx imen_mtx;
-
/* lock region used by kernel profiling */
int mcount_lock;
diff --git a/sys/amd64/isa/clock.c b/sys/amd64/isa/clock.c
index a7aaea0..a39f773 100644
--- a/sys/amd64/isa/clock.c
+++ b/sys/amd64/isa/clock.c
@@ -1026,7 +1026,9 @@ cpu_initclocks()
inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL,
INTR_TYPE_CLK | INTR_FAST, &clkdesc);
+ mtx_lock_spin(&icu_lock);
INTREN(1 << apic_8254_intr);
+ mtx_unlock_spin(&icu_lock);
#else /* APIC_IO */
@@ -1037,7 +1039,9 @@ cpu_initclocks()
*/
inthand_add("clk", 0, (driver_intr_t *)clkintr, NULL,
INTR_TYPE_CLK | INTR_FAST, NULL);
+ mtx_lock_spin(&icu_lock);
INTREN(IRQ0);
+ mtx_unlock_spin(&icu_lock);
#endif /* APIC_IO */
@@ -1060,11 +1064,13 @@ cpu_initclocks()
inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL,
INTR_TYPE_CLK | INTR_FAST, NULL);
+ mtx_lock_spin(&icu_lock);
#ifdef APIC_IO
INTREN(APIC_IRQ8);
#else
INTREN(IRQ8);
#endif /* APIC_IO */
+ mtx_unlock_spin(&icu_lock);
writertc(RTC_STATUSB, rtc_statusb);
@@ -1081,7 +1087,9 @@ cpu_initclocks()
* on the IO APIC.
* Workaround: Limited variant of mixed mode.
*/
+ mtx_lock_spin(&icu_lock);
INTRDIS(1 << apic_8254_intr);
+ mtx_unlock_spin(&icu_lock);
inthand_remove(clkdesc);
printf("APIC_IO: Broken MP table detected: "
"8254 is not connected to "
@@ -1104,7 +1112,9 @@ cpu_initclocks()
inthand_add("clk", apic_8254_intr,
(driver_intr_t *)clkintr, NULL,
INTR_TYPE_CLK | INTR_FAST, NULL);
+ mtx_lock_spin(&icu_lock);
INTREN(1 << apic_8254_intr);
+ mtx_unlock_spin(&icu_lock);
}
}
diff --git a/sys/amd64/isa/intr_machdep.c b/sys/amd64/isa/intr_machdep.c
index c17806f..3d20f9f 100644
--- a/sys/amd64/isa/intr_machdep.c
+++ b/sys/amd64/isa/intr_machdep.c
@@ -289,14 +289,13 @@ isa_nmi(cd)
void icu_reinit()
{
int i;
- u_int32_t eflags;
- eflags = read_eflags();
- disable_intr();
+
+ mtx_lock_spin(&icu_lock);
init_i8259();
for(i=0;i<ICU_LEN;i++)
if(intr_handler[i] != isa_strayintr)
INTREN(1<<i);
- write_eflags(eflags);
+ mtx_unlock_spin(&icu_lock);
}
/*
@@ -312,7 +311,9 @@ isa_defaultirq()
/* icu vectors */
for (i = 0; i < ICU_LEN; i++)
icu_unset(i, (driver_intr_t *)NULL);
+ mtx_lock_spin(&icu_lock);
init_i8259();
+ mtx_unlock_spin(&icu_lock);
}
@@ -406,8 +407,10 @@ isa_irq_pending()
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);
}
#endif
@@ -473,7 +476,6 @@ icu_setup(int intr, driver_intr_t *handler, void *arg, int flags)
int vector;
u_int32_t value; /* the window register is 32 bits */
#endif /* FAST_HI */
- u_long ef;
#if defined(APIC_IO)
if ((u_int)intr >= ICU_LEN) /* no 8259 SLAVE to ignore */
@@ -486,8 +488,7 @@ icu_setup(int intr, driver_intr_t *handler, void *arg, int flags)
return (EBUSY);
#endif
- ef = read_eflags();
- disable_intr();
+ mtx_lock_spin(&icu_lock);
intr_handler[intr] = handler;
intr_unit[intr] = arg;
#ifdef FAST_HI
@@ -528,7 +529,7 @@ icu_setup(int intr, driver_intr_t *handler, void *arg, int flags)
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
#endif /* FAST_HI */
INTREN(1 << intr);
- write_eflags(ef);
+ mtx_unlock_spin(&icu_lock);
return (0);
}
@@ -542,14 +543,12 @@ icu_unset(intr, handler)
int intr;
driver_intr_t *handler;
{
- u_long ef;
if ((u_int)intr >= ICU_LEN || handler != intr_handler[intr])
return (EINVAL);
+ mtx_lock_spin(&icu_lock);
INTRDIS(1 << intr);
- ef = read_eflags();
- disable_intr();
intr_countp[intr] = &intrcnt[1 + intr];
intr_handler[intr] = isa_strayintr;
intr_unit[intr] = &intr_unit[intr];
@@ -564,7 +563,7 @@ icu_unset(intr, handler)
setidt(ICU_OFFSET + intr, slowintr[intr], SDT_SYS386IGT, SEL_KPL,
GSEL(GCODE_SEL, SEL_KPL));
#endif /* FAST_HI */
- write_eflags(ef);
+ mtx_unlock_spin(&icu_lock);
return (0);
}
@@ -580,14 +579,18 @@ static void
ithread_enable(int vector)
{
+ mtx_lock_spin(&icu_lock);
INTREN(1 << vector);
+ mtx_unlock_spin(&icu_lock);
}
static void
ithread_disable(int vector)
{
+ mtx_lock_spin(&icu_lock);
INTRDIS(1 << vector);
+ mtx_unlock_spin(&icu_lock);
}
int
diff --git a/sys/amd64/isa/intr_machdep.h b/sys/amd64/isa/intr_machdep.h
index 39bffb9..1726635 100644
--- a/sys/amd64/isa/intr_machdep.h
+++ b/sys/amd64/isa/intr_machdep.h
@@ -126,7 +126,15 @@
#endif /* SMP || APIC_IO */
-#ifndef LOCORE
+#ifdef LOCORE
+
+/*
+ * Protects the IO APIC, 8259 PIC, imen, and apic_imen
+ */
+#define ICU_LOCK MTX_LOCK_SPIN(icu_lock, 0)
+#define ICU_UNLOCK MTX_UNLOCK_SPIN(icu_lock)
+
+#else /* LOCORE */
/*
* Type of the first (asm) part of an interrupt handler.
@@ -139,6 +147,7 @@ extern u_long *intr_countp[]; /* pointers into intrcnt[] */
extern driver_intr_t *intr_handler[]; /* C entry points of intr handlers */
extern struct ithd *ithds[];
extern void *intr_unit[]; /* cookies to pass to intr handlers */
+extern struct mtx icu_lock;
inthand_t
IDTVEC(fastintr0), IDTVEC(fastintr1),
diff --git a/sys/amd64/isa/nmi.c b/sys/amd64/isa/nmi.c
index c17806f..3d20f9f 100644
--- a/sys/amd64/isa/nmi.c
+++ b/sys/amd64/isa/nmi.c
@@ -289,14 +289,13 @@ isa_nmi(cd)
void icu_reinit()
{
int i;
- u_int32_t eflags;
- eflags = read_eflags();
- disable_intr();
+
+ mtx_lock_spin(&icu_lock);
init_i8259();
for(i=0;i<ICU_LEN;i++)
if(intr_handler[i] != isa_strayintr)
INTREN(1<<i);
- write_eflags(eflags);
+ mtx_unlock_spin(&icu_lock);
}
/*
@@ -312,7 +311,9 @@ isa_defaultirq()
/* icu vectors */
for (i = 0; i < ICU_LEN; i++)
icu_unset(i, (driver_intr_t *)NULL);
+ mtx_lock_spin(&icu_lock);
init_i8259();
+ mtx_unlock_spin(&icu_lock);
}
@@ -406,8 +407,10 @@ isa_irq_pending()
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);
}
#endif
@@ -473,7 +476,6 @@ icu_setup(int intr, driver_intr_t *handler, void *arg, int flags)
int vector;
u_int32_t value; /* the window register is 32 bits */
#endif /* FAST_HI */
- u_long ef;
#if defined(APIC_IO)
if ((u_int)intr >= ICU_LEN) /* no 8259 SLAVE to ignore */
@@ -486,8 +488,7 @@ icu_setup(int intr, driver_intr_t *handler, void *arg, int flags)
return (EBUSY);
#endif
- ef = read_eflags();
- disable_intr();
+ mtx_lock_spin(&icu_lock);
intr_handler[intr] = handler;
intr_unit[intr] = arg;
#ifdef FAST_HI
@@ -528,7 +529,7 @@ icu_setup(int intr, driver_intr_t *handler, void *arg, int flags)
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
#endif /* FAST_HI */
INTREN(1 << intr);
- write_eflags(ef);
+ mtx_unlock_spin(&icu_lock);
return (0);
}
@@ -542,14 +543,12 @@ icu_unset(intr, handler)
int intr;
driver_intr_t *handler;
{
- u_long ef;
if ((u_int)intr >= ICU_LEN || handler != intr_handler[intr])
return (EINVAL);
+ mtx_lock_spin(&icu_lock);
INTRDIS(1 << intr);
- ef = read_eflags();
- disable_intr();
intr_countp[intr] = &intrcnt[1 + intr];
intr_handler[intr] = isa_strayintr;
intr_unit[intr] = &intr_unit[intr];
@@ -564,7 +563,7 @@ icu_unset(intr, handler)
setidt(ICU_OFFSET + intr, slowintr[intr], SDT_SYS386IGT, SEL_KPL,
GSEL(GCODE_SEL, SEL_KPL));
#endif /* FAST_HI */
- write_eflags(ef);
+ mtx_unlock_spin(&icu_lock);
return (0);
}
@@ -580,14 +579,18 @@ static void
ithread_enable(int vector)
{
+ mtx_lock_spin(&icu_lock);
INTREN(1 << vector);
+ mtx_unlock_spin(&icu_lock);
}
static void
ithread_disable(int vector)
{
+ mtx_lock_spin(&icu_lock);
INTRDIS(1 << vector);
+ mtx_unlock_spin(&icu_lock);
}
int
diff --git a/sys/amd64/isa/npx.c b/sys/amd64/isa/npx.c
index 34a822a..5d44aaa 100644
--- a/sys/amd64/isa/npx.c
+++ b/sys/amd64/isa/npx.c
@@ -82,6 +82,7 @@
#include <i386/isa/isa.h>
#endif
#endif
+#include <i386/isa/intr_machdep.h>
#include <isa/isavar.h>
/*
@@ -425,7 +426,9 @@ no_irq13:
* XXX hack around brokenness of bus_teardown_intr(). If we left the
* irq active then we would get it instead of exception 16.
*/
+ mtx_lock_spin(&icu_lock);
INTRDIS(1 << irq_num);
+ mtx_unlock_spin(&icu_lock);
bus_release_resource(dev, SYS_RES_IRQ, irq_rid, irq_res);
bus_release_resource(dev, SYS_RES_IOPORT, ioport_rid, ioport_res);
diff --git a/sys/amd64/isa/vector.S b/sys/amd64/isa/vector.S
index d3b7a89..0bed76f 100644
--- a/sys/amd64/isa/vector.S
+++ b/sys/amd64/isa/vector.S
@@ -15,6 +15,7 @@
#else
#include <i386/isa/isa.h>
#endif
+#include <i386/isa/intr_machdep.h>
#define FAST_INTR_HANDLER_USES_ES 1
#ifdef FAST_INTR_HANDLER_USES_ES
diff --git a/sys/amd64/isa/vector.s b/sys/amd64/isa/vector.s
index d3b7a89..0bed76f 100644
--- a/sys/amd64/isa/vector.s
+++ b/sys/amd64/isa/vector.s
@@ -15,6 +15,7 @@
#else
#include <i386/isa/isa.h>
#endif
+#include <i386/isa/intr_machdep.h>
#define FAST_INTR_HANDLER_USES_ES 1
#ifdef FAST_INTR_HANDLER_USES_ES
diff --git a/sys/i386/i386/apic_vector.s b/sys/i386/i386/apic_vector.s
index 3d7a687..6147b31 100644
--- a/sys/i386/i386/apic_vector.s
+++ b/sys/i386/i386/apic_vector.s
@@ -7,8 +7,6 @@
#include <machine/apic.h>
#include <machine/smp.h>
-#include "i386/isa/intr_machdep.h"
-
/* convert an absolute IRQ# into a bitmask */
#define IRQ_BIT(irq_num) (1 << (irq_num))
@@ -67,7 +65,7 @@ IDTVEC(vec_name) ; \
#define REDIRIDX(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 12
#define MASK_IRQ(irq_num) \
- IMASK_LOCK ; /* into critical reg */ \
+ ICU_LOCK ; /* into critical reg */ \
testl $IRQ_BIT(irq_num), apic_imen ; \
jne 7f ; /* masked, don't mask */ \
orl $IRQ_BIT(irq_num), apic_imen ; /* set the mask bit */ \
@@ -78,7 +76,7 @@ IDTVEC(vec_name) ; \
orl $IOART_INTMASK, %eax ; /* set the mask */ \
movl %eax, IOAPIC_WINDOW(%ecx) ; /* new value */ \
7: ; /* already masked */ \
- IMASK_UNLOCK
+ ICU_UNLOCK
/*
* Test to see whether we are handling an edge or level triggered INT.
* Level-triggered INTs must still be masked as we don't clear the source,
@@ -113,7 +111,7 @@ IDTVEC(vec_name) ; \
* Test to see if the source is currently masked, clear if so.
*/
#define UNMASK_IRQ(irq_num) \
- IMASK_LOCK ; /* into critical reg */ \
+ ICU_LOCK ; /* into critical reg */ \
testl $IRQ_BIT(irq_num), _apic_imen ; \
je 7f ; /* bit clear, not masked */ \
andl $~IRQ_BIT(irq_num), _apic_imen ;/* clear mask bit */ \
@@ -124,7 +122,7 @@ IDTVEC(vec_name) ; \
andl $~IOART_INTMASK, %eax ; /* clear the mask */ \
movl %eax, IOAPIC_WINDOW(%ecx) ; /* new value */ \
7: ; /* already unmasked */ \
- IMASK_UNLOCK
+ ICU_UNLOCK
/*
* Slow, threaded interrupts.
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index c2ef5dc..349a140 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -211,6 +211,7 @@ static struct pcpu __pcpu;
struct mtx sched_lock;
struct mtx Giant;
+struct mtx icu_lock;
static void
cpu_startup(dummy)
@@ -1744,9 +1745,7 @@ init386(first)
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);
-#ifdef SMP
- mtx_init(&imen_mtx, "imen", MTX_SPIN);
-#endif
+ mtx_init(&icu_lock, "icu", MTX_SPIN);
mtx_lock(&Giant);
/* make ldt memory segments */
diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c
index e8da25b..1feb66a 100644
--- a/sys/i386/i386/mp_machdep.c
+++ b/sys/i386/i386/mp_machdep.c
@@ -320,9 +320,6 @@ static void release_aps(void *dummy);
* initialize all the SMP locks
*/
-/* critical region around IO APIC, apic_imen */
-struct mtx imen_mtx;
-
/* lock region used by kernel profiling */
int mcount_lock;
diff --git a/sys/i386/i386/mpapic.c b/sys/i386/i386/mpapic.c
index 7e3478a..aa9eaefd 100644
--- a/sys/i386/i386/mpapic.c
+++ b/sys/i386/i386/mpapic.c
@@ -210,11 +210,11 @@ io_apic_setup_intpin(int apic, int pin)
* shouldn't and stop the carnage.
*/
vector = NRSVIDT + pin; /* IDT vec */
- mtx_lock_spin(&imen_mtx);
+ mtx_lock_spin(&icu_lock);
io_apic_write(apic, select,
(io_apic_read(apic, select) & ~IOART_INTMASK
& ~0xff)|IOART_INTMSET|vector);
- mtx_unlock_spin(&imen_mtx);
+ mtx_unlock_spin(&icu_lock);
/* we only deal with vectored INTs here */
if (apic_int_type(apic, pin) != 0)
@@ -258,10 +258,10 @@ io_apic_setup_intpin(int apic, int pin)
printf("IOAPIC #%d intpin %d -> irq %d\n",
apic, pin, irq);
vector = NRSVIDT + irq; /* IDT vec */
- mtx_lock_spin(&imen_mtx);
+ mtx_lock_spin(&icu_lock);
io_apic_write(apic, select, flags | vector);
io_apic_write(apic, select + 1, target);
- mtx_unlock_spin(&imen_mtx);
+ mtx_unlock_spin(&icu_lock);
}
int
diff --git a/sys/i386/i386/mptable.c b/sys/i386/i386/mptable.c
index e8da25b..1feb66a 100644
--- a/sys/i386/i386/mptable.c
+++ b/sys/i386/i386/mptable.c
@@ -320,9 +320,6 @@ static void release_aps(void *dummy);
* initialize all the SMP locks
*/
-/* critical region around IO APIC, apic_imen */
-struct mtx imen_mtx;
-
/* lock region used by kernel profiling */
int mcount_lock;
diff --git a/sys/i386/i386/tsc.c b/sys/i386/i386/tsc.c
index a7aaea0..a39f773 100644
--- a/sys/i386/i386/tsc.c
+++ b/sys/i386/i386/tsc.c
@@ -1026,7 +1026,9 @@ cpu_initclocks()
inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL,
INTR_TYPE_CLK | INTR_FAST, &clkdesc);
+ mtx_lock_spin(&icu_lock);
INTREN(1 << apic_8254_intr);
+ mtx_unlock_spin(&icu_lock);
#else /* APIC_IO */
@@ -1037,7 +1039,9 @@ cpu_initclocks()
*/
inthand_add("clk", 0, (driver_intr_t *)clkintr, NULL,
INTR_TYPE_CLK | INTR_FAST, NULL);
+ mtx_lock_spin(&icu_lock);
INTREN(IRQ0);
+ mtx_unlock_spin(&icu_lock);
#endif /* APIC_IO */
@@ -1060,11 +1064,13 @@ cpu_initclocks()
inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL,
INTR_TYPE_CLK | INTR_FAST, NULL);
+ mtx_lock_spin(&icu_lock);
#ifdef APIC_IO
INTREN(APIC_IRQ8);
#else
INTREN(IRQ8);
#endif /* APIC_IO */
+ mtx_unlock_spin(&icu_lock);
writertc(RTC_STATUSB, rtc_statusb);
@@ -1081,7 +1087,9 @@ cpu_initclocks()
* on the IO APIC.
* Workaround: Limited variant of mixed mode.
*/
+ mtx_lock_spin(&icu_lock);
INTRDIS(1 << apic_8254_intr);
+ mtx_unlock_spin(&icu_lock);
inthand_remove(clkdesc);
printf("APIC_IO: Broken MP table detected: "
"8254 is not connected to "
@@ -1104,7 +1112,9 @@ cpu_initclocks()
inthand_add("clk", apic_8254_intr,
(driver_intr_t *)clkintr, NULL,
INTR_TYPE_CLK | INTR_FAST, NULL);
+ mtx_lock_spin(&icu_lock);
INTREN(1 << apic_8254_intr);
+ mtx_unlock_spin(&icu_lock);
}
}
diff --git a/sys/i386/include/apic.h b/sys/i386/include/apic.h
index 6345ce7..70b8011 100644
--- a/sys/i386/include/apic.h
+++ b/sys/i386/include/apic.h
@@ -458,28 +458,4 @@ typedef struct IOAPIC ioapic_t;
#define IOART_INTVEC 0x000000ff /* R/W: INTerrupt vector field */
-#ifdef LOCORE
-
-#ifdef SMP
-
-/*
- * Protects the IO APIC and apic_imen as a critical region.
- */
-#define IMASK_LOCK MTX_LOCK_SPIN(imen_mtx, 0)
-#define IMASK_UNLOCK MTX_UNLOCK_SPIN(imen_mtx)
-
-#else /* SMP */
-
-#define IMASK_LOCK /* NOP */
-#define IMASK_UNLOCK /* NOP */
-
-#endif /* SMP */
-
-#else /* LOCORE */
-
-/* global data in mp_machdep.c */
-extern struct mtx imen_mtx;
-
-#endif /* LOCORE */
-
#endif /* _MACHINE_APIC_H_ */
diff --git a/sys/i386/include/apicreg.h b/sys/i386/include/apicreg.h
index 6345ce7..70b8011 100644
--- a/sys/i386/include/apicreg.h
+++ b/sys/i386/include/apicreg.h
@@ -458,28 +458,4 @@ typedef struct IOAPIC ioapic_t;
#define IOART_INTVEC 0x000000ff /* R/W: INTerrupt vector field */
-#ifdef LOCORE
-
-#ifdef SMP
-
-/*
- * Protects the IO APIC and apic_imen as a critical region.
- */
-#define IMASK_LOCK MTX_LOCK_SPIN(imen_mtx, 0)
-#define IMASK_UNLOCK MTX_UNLOCK_SPIN(imen_mtx)
-
-#else /* SMP */
-
-#define IMASK_LOCK /* NOP */
-#define IMASK_UNLOCK /* NOP */
-
-#endif /* SMP */
-
-#else /* LOCORE */
-
-/* global data in mp_machdep.c */
-extern struct mtx imen_mtx;
-
-#endif /* LOCORE */
-
#endif /* _MACHINE_APIC_H_ */
diff --git a/sys/i386/include/mptable.h b/sys/i386/include/mptable.h
index e8da25b..1feb66a 100644
--- a/sys/i386/include/mptable.h
+++ b/sys/i386/include/mptable.h
@@ -320,9 +320,6 @@ static void release_aps(void *dummy);
* initialize all the SMP locks
*/
-/* critical region around IO APIC, apic_imen */
-struct mtx imen_mtx;
-
/* lock region used by kernel profiling */
int mcount_lock;
diff --git a/sys/i386/isa/apic_ipl.s b/sys/i386/isa/apic_ipl.s
index b448193..96817ef 100644
--- a/sys/i386/isa/apic_ipl.s
+++ b/sys/i386/isa/apic_ipl.s
@@ -74,11 +74,7 @@ bad_mask: .asciz "bad mask"
* It sets the mask bit of the associated IO APIC register.
*/
ENTRY(INTREN)
- pushfl /* save state of EI flag */
- cli /* prevent recursion */
- IMASK_LOCK /* enter critical reg */
-
- movl 8(%esp), %eax /* mask into %eax */
+ movl 4(%esp), %eax /* mask into %eax */
bsfl %eax, %ecx /* get pin index */
btrl %ecx, apic_imen /* update apic_imen */
@@ -91,12 +87,10 @@ ENTRY(INTREN)
jz 1f
movl %ecx, (%edx) /* write the target register index */
- movl 16(%edx), %eax /* read the target register data */
+ movl IOAPIC_WINDOW(%edx), %eax /* read the target register data */
andl $~IOART_INTMASK, %eax /* clear mask bit */
- movl %eax, 16(%edx) /* write the APIC register data */
+ movl %eax, IOAPIC_WINDOW(%edx) /* write the APIC register data */
1:
- IMASK_UNLOCK /* exit critical reg */
- popfl /* restore old state of EI flag */
ret
/*
@@ -106,11 +100,7 @@ ENTRY(INTREN)
* It clears the mask bit of the associated IO APIC register.
*/
ENTRY(INTRDIS)
- pushfl /* save state of EI flag */
- cli /* prevent recursion */
- IMASK_LOCK /* enter critical reg */
-
- movl 8(%esp), %eax /* mask into %eax */
+ movl 4(%esp), %eax /* mask into %eax */
bsfl %eax, %ecx /* get pin index */
btsl %ecx, apic_imen /* update apic_imen */
@@ -123,10 +113,8 @@ ENTRY(INTRDIS)
jz 1f
movl %ecx, (%edx) /* write the target register index */
- movl 16(%edx), %eax /* read the target register data */
+ movl IOAPIC_WINDOW(%edx), %eax /* read the target register data */
orl $IOART_INTMASK, %eax /* set mask bit */
- movl %eax, 16(%edx) /* write the APIC register data */
+ movl %eax, IOAPIC_WINDOW(%edx) /* write the APIC register data */
1:
- IMASK_UNLOCK /* exit critical reg */
- popfl /* restore old state of EI flag */
ret
diff --git a/sys/i386/isa/apic_vector.s b/sys/i386/isa/apic_vector.s
index 3d7a687..6147b31 100644
--- a/sys/i386/isa/apic_vector.s
+++ b/sys/i386/isa/apic_vector.s
@@ -7,8 +7,6 @@
#include <machine/apic.h>
#include <machine/smp.h>
-#include "i386/isa/intr_machdep.h"
-
/* convert an absolute IRQ# into a bitmask */
#define IRQ_BIT(irq_num) (1 << (irq_num))
@@ -67,7 +65,7 @@ IDTVEC(vec_name) ; \
#define REDIRIDX(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 12
#define MASK_IRQ(irq_num) \
- IMASK_LOCK ; /* into critical reg */ \
+ ICU_LOCK ; /* into critical reg */ \
testl $IRQ_BIT(irq_num), apic_imen ; \
jne 7f ; /* masked, don't mask */ \
orl $IRQ_BIT(irq_num), apic_imen ; /* set the mask bit */ \
@@ -78,7 +76,7 @@ IDTVEC(vec_name) ; \
orl $IOART_INTMASK, %eax ; /* set the mask */ \
movl %eax, IOAPIC_WINDOW(%ecx) ; /* new value */ \
7: ; /* already masked */ \
- IMASK_UNLOCK
+ ICU_UNLOCK
/*
* Test to see whether we are handling an edge or level triggered INT.
* Level-triggered INTs must still be masked as we don't clear the source,
@@ -113,7 +111,7 @@ IDTVEC(vec_name) ; \
* Test to see if the source is currently masked, clear if so.
*/
#define UNMASK_IRQ(irq_num) \
- IMASK_LOCK ; /* into critical reg */ \
+ ICU_LOCK ; /* into critical reg */ \
testl $IRQ_BIT(irq_num), _apic_imen ; \
je 7f ; /* bit clear, not masked */ \
andl $~IRQ_BIT(irq_num), _apic_imen ;/* clear mask bit */ \
@@ -124,7 +122,7 @@ IDTVEC(vec_name) ; \
andl $~IOART_INTMASK, %eax ; /* clear the mask */ \
movl %eax, IOAPIC_WINDOW(%ecx) ; /* new value */ \
7: ; /* already unmasked */ \
- IMASK_UNLOCK
+ ICU_UNLOCK
/*
* Slow, threaded interrupts.
diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c
index a7aaea0..a39f773 100644
--- a/sys/i386/isa/clock.c
+++ b/sys/i386/isa/clock.c
@@ -1026,7 +1026,9 @@ cpu_initclocks()
inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL,
INTR_TYPE_CLK | INTR_FAST, &clkdesc);
+ mtx_lock_spin(&icu_lock);
INTREN(1 << apic_8254_intr);
+ mtx_unlock_spin(&icu_lock);
#else /* APIC_IO */
@@ -1037,7 +1039,9 @@ cpu_initclocks()
*/
inthand_add("clk", 0, (driver_intr_t *)clkintr, NULL,
INTR_TYPE_CLK | INTR_FAST, NULL);
+ mtx_lock_spin(&icu_lock);
INTREN(IRQ0);
+ mtx_unlock_spin(&icu_lock);
#endif /* APIC_IO */
@@ -1060,11 +1064,13 @@ cpu_initclocks()
inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL,
INTR_TYPE_CLK | INTR_FAST, NULL);
+ mtx_lock_spin(&icu_lock);
#ifdef APIC_IO
INTREN(APIC_IRQ8);
#else
INTREN(IRQ8);
#endif /* APIC_IO */
+ mtx_unlock_spin(&icu_lock);
writertc(RTC_STATUSB, rtc_statusb);
@@ -1081,7 +1087,9 @@ cpu_initclocks()
* on the IO APIC.
* Workaround: Limited variant of mixed mode.
*/
+ mtx_lock_spin(&icu_lock);
INTRDIS(1 << apic_8254_intr);
+ mtx_unlock_spin(&icu_lock);
inthand_remove(clkdesc);
printf("APIC_IO: Broken MP table detected: "
"8254 is not connected to "
@@ -1104,7 +1112,9 @@ cpu_initclocks()
inthand_add("clk", apic_8254_intr,
(driver_intr_t *)clkintr, NULL,
INTR_TYPE_CLK | INTR_FAST, NULL);
+ mtx_lock_spin(&icu_lock);
INTREN(1 << apic_8254_intr);
+ mtx_unlock_spin(&icu_lock);
}
}
diff --git a/sys/i386/isa/intr_machdep.c b/sys/i386/isa/intr_machdep.c
index c17806f..3d20f9f 100644
--- a/sys/i386/isa/intr_machdep.c
+++ b/sys/i386/isa/intr_machdep.c
@@ -289,14 +289,13 @@ isa_nmi(cd)
void icu_reinit()
{
int i;
- u_int32_t eflags;
- eflags = read_eflags();
- disable_intr();
+
+ mtx_lock_spin(&icu_lock);
init_i8259();
for(i=0;i<ICU_LEN;i++)
if(intr_handler[i] != isa_strayintr)
INTREN(1<<i);
- write_eflags(eflags);
+ mtx_unlock_spin(&icu_lock);
}
/*
@@ -312,7 +311,9 @@ isa_defaultirq()
/* icu vectors */
for (i = 0; i < ICU_LEN; i++)
icu_unset(i, (driver_intr_t *)NULL);
+ mtx_lock_spin(&icu_lock);
init_i8259();
+ mtx_unlock_spin(&icu_lock);
}
@@ -406,8 +407,10 @@ isa_irq_pending()
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);
}
#endif
@@ -473,7 +476,6 @@ icu_setup(int intr, driver_intr_t *handler, void *arg, int flags)
int vector;
u_int32_t value; /* the window register is 32 bits */
#endif /* FAST_HI */
- u_long ef;
#if defined(APIC_IO)
if ((u_int)intr >= ICU_LEN) /* no 8259 SLAVE to ignore */
@@ -486,8 +488,7 @@ icu_setup(int intr, driver_intr_t *handler, void *arg, int flags)
return (EBUSY);
#endif
- ef = read_eflags();
- disable_intr();
+ mtx_lock_spin(&icu_lock);
intr_handler[intr] = handler;
intr_unit[intr] = arg;
#ifdef FAST_HI
@@ -528,7 +529,7 @@ icu_setup(int intr, driver_intr_t *handler, void *arg, int flags)
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
#endif /* FAST_HI */
INTREN(1 << intr);
- write_eflags(ef);
+ mtx_unlock_spin(&icu_lock);
return (0);
}
@@ -542,14 +543,12 @@ icu_unset(intr, handler)
int intr;
driver_intr_t *handler;
{
- u_long ef;
if ((u_int)intr >= ICU_LEN || handler != intr_handler[intr])
return (EINVAL);
+ mtx_lock_spin(&icu_lock);
INTRDIS(1 << intr);
- ef = read_eflags();
- disable_intr();
intr_countp[intr] = &intrcnt[1 + intr];
intr_handler[intr] = isa_strayintr;
intr_unit[intr] = &intr_unit[intr];
@@ -564,7 +563,7 @@ icu_unset(intr, handler)
setidt(ICU_OFFSET + intr, slowintr[intr], SDT_SYS386IGT, SEL_KPL,
GSEL(GCODE_SEL, SEL_KPL));
#endif /* FAST_HI */
- write_eflags(ef);
+ mtx_unlock_spin(&icu_lock);
return (0);
}
@@ -580,14 +579,18 @@ static void
ithread_enable(int vector)
{
+ mtx_lock_spin(&icu_lock);
INTREN(1 << vector);
+ mtx_unlock_spin(&icu_lock);
}
static void
ithread_disable(int vector)
{
+ mtx_lock_spin(&icu_lock);
INTRDIS(1 << vector);
+ mtx_unlock_spin(&icu_lock);
}
int
diff --git a/sys/i386/isa/intr_machdep.h b/sys/i386/isa/intr_machdep.h
index 39bffb9..1726635 100644
--- a/sys/i386/isa/intr_machdep.h
+++ b/sys/i386/isa/intr_machdep.h
@@ -126,7 +126,15 @@
#endif /* SMP || APIC_IO */
-#ifndef LOCORE
+#ifdef LOCORE
+
+/*
+ * Protects the IO APIC, 8259 PIC, imen, and apic_imen
+ */
+#define ICU_LOCK MTX_LOCK_SPIN(icu_lock, 0)
+#define ICU_UNLOCK MTX_UNLOCK_SPIN(icu_lock)
+
+#else /* LOCORE */
/*
* Type of the first (asm) part of an interrupt handler.
@@ -139,6 +147,7 @@ extern u_long *intr_countp[]; /* pointers into intrcnt[] */
extern driver_intr_t *intr_handler[]; /* C entry points of intr handlers */
extern struct ithd *ithds[];
extern void *intr_unit[]; /* cookies to pass to intr handlers */
+extern struct mtx icu_lock;
inthand_t
IDTVEC(fastintr0), IDTVEC(fastintr1),
diff --git a/sys/i386/isa/nmi.c b/sys/i386/isa/nmi.c
index c17806f..3d20f9f 100644
--- a/sys/i386/isa/nmi.c
+++ b/sys/i386/isa/nmi.c
@@ -289,14 +289,13 @@ isa_nmi(cd)
void icu_reinit()
{
int i;
- u_int32_t eflags;
- eflags = read_eflags();
- disable_intr();
+
+ mtx_lock_spin(&icu_lock);
init_i8259();
for(i=0;i<ICU_LEN;i++)
if(intr_handler[i] != isa_strayintr)
INTREN(1<<i);
- write_eflags(eflags);
+ mtx_unlock_spin(&icu_lock);
}
/*
@@ -312,7 +311,9 @@ isa_defaultirq()
/* icu vectors */
for (i = 0; i < ICU_LEN; i++)
icu_unset(i, (driver_intr_t *)NULL);
+ mtx_lock_spin(&icu_lock);
init_i8259();
+ mtx_unlock_spin(&icu_lock);
}
@@ -406,8 +407,10 @@ isa_irq_pending()
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);
}
#endif
@@ -473,7 +476,6 @@ icu_setup(int intr, driver_intr_t *handler, void *arg, int flags)
int vector;
u_int32_t value; /* the window register is 32 bits */
#endif /* FAST_HI */
- u_long ef;
#if defined(APIC_IO)
if ((u_int)intr >= ICU_LEN) /* no 8259 SLAVE to ignore */
@@ -486,8 +488,7 @@ icu_setup(int intr, driver_intr_t *handler, void *arg, int flags)
return (EBUSY);
#endif
- ef = read_eflags();
- disable_intr();
+ mtx_lock_spin(&icu_lock);
intr_handler[intr] = handler;
intr_unit[intr] = arg;
#ifdef FAST_HI
@@ -528,7 +529,7 @@ icu_setup(int intr, driver_intr_t *handler, void *arg, int flags)
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
#endif /* FAST_HI */
INTREN(1 << intr);
- write_eflags(ef);
+ mtx_unlock_spin(&icu_lock);
return (0);
}
@@ -542,14 +543,12 @@ icu_unset(intr, handler)
int intr;
driver_intr_t *handler;
{
- u_long ef;
if ((u_int)intr >= ICU_LEN || handler != intr_handler[intr])
return (EINVAL);
+ mtx_lock_spin(&icu_lock);
INTRDIS(1 << intr);
- ef = read_eflags();
- disable_intr();
intr_countp[intr] = &intrcnt[1 + intr];
intr_handler[intr] = isa_strayintr;
intr_unit[intr] = &intr_unit[intr];
@@ -564,7 +563,7 @@ icu_unset(intr, handler)
setidt(ICU_OFFSET + intr, slowintr[intr], SDT_SYS386IGT, SEL_KPL,
GSEL(GCODE_SEL, SEL_KPL));
#endif /* FAST_HI */
- write_eflags(ef);
+ mtx_unlock_spin(&icu_lock);
return (0);
}
@@ -580,14 +579,18 @@ static void
ithread_enable(int vector)
{
+ mtx_lock_spin(&icu_lock);
INTREN(1 << vector);
+ mtx_unlock_spin(&icu_lock);
}
static void
ithread_disable(int vector)
{
+ mtx_lock_spin(&icu_lock);
INTRDIS(1 << vector);
+ mtx_unlock_spin(&icu_lock);
}
int
diff --git a/sys/i386/isa/npx.c b/sys/i386/isa/npx.c
index 34a822a..5d44aaa 100644
--- a/sys/i386/isa/npx.c
+++ b/sys/i386/isa/npx.c
@@ -82,6 +82,7 @@
#include <i386/isa/isa.h>
#endif
#endif
+#include <i386/isa/intr_machdep.h>
#include <isa/isavar.h>
/*
@@ -425,7 +426,9 @@ no_irq13:
* XXX hack around brokenness of bus_teardown_intr(). If we left the
* irq active then we would get it instead of exception 16.
*/
+ mtx_lock_spin(&icu_lock);
INTRDIS(1 << irq_num);
+ mtx_unlock_spin(&icu_lock);
bus_release_resource(dev, SYS_RES_IRQ, irq_rid, irq_res);
bus_release_resource(dev, SYS_RES_IOPORT, ioport_rid, ioport_res);
diff --git a/sys/i386/isa/vector.s b/sys/i386/isa/vector.s
index d3b7a89..0bed76f 100644
--- a/sys/i386/isa/vector.s
+++ b/sys/i386/isa/vector.s
@@ -15,6 +15,7 @@
#else
#include <i386/isa/isa.h>
#endif
+#include <i386/isa/intr_machdep.h>
#define FAST_INTR_HANDLER_USES_ES 1
#ifdef FAST_INTR_HANDLER_USES_ES
diff --git a/sys/isa/atrtc.c b/sys/isa/atrtc.c
index a7aaea0..a39f773 100644
--- a/sys/isa/atrtc.c
+++ b/sys/isa/atrtc.c
@@ -1026,7 +1026,9 @@ cpu_initclocks()
inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL,
INTR_TYPE_CLK | INTR_FAST, &clkdesc);
+ mtx_lock_spin(&icu_lock);
INTREN(1 << apic_8254_intr);
+ mtx_unlock_spin(&icu_lock);
#else /* APIC_IO */
@@ -1037,7 +1039,9 @@ cpu_initclocks()
*/
inthand_add("clk", 0, (driver_intr_t *)clkintr, NULL,
INTR_TYPE_CLK | INTR_FAST, NULL);
+ mtx_lock_spin(&icu_lock);
INTREN(IRQ0);
+ mtx_unlock_spin(&icu_lock);
#endif /* APIC_IO */
@@ -1060,11 +1064,13 @@ cpu_initclocks()
inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL,
INTR_TYPE_CLK | INTR_FAST, NULL);
+ mtx_lock_spin(&icu_lock);
#ifdef APIC_IO
INTREN(APIC_IRQ8);
#else
INTREN(IRQ8);
#endif /* APIC_IO */
+ mtx_unlock_spin(&icu_lock);
writertc(RTC_STATUSB, rtc_statusb);
@@ -1081,7 +1087,9 @@ cpu_initclocks()
* on the IO APIC.
* Workaround: Limited variant of mixed mode.
*/
+ mtx_lock_spin(&icu_lock);
INTRDIS(1 << apic_8254_intr);
+ mtx_unlock_spin(&icu_lock);
inthand_remove(clkdesc);
printf("APIC_IO: Broken MP table detected: "
"8254 is not connected to "
@@ -1104,7 +1112,9 @@ cpu_initclocks()
inthand_add("clk", apic_8254_intr,
(driver_intr_t *)clkintr, NULL,
INTR_TYPE_CLK | INTR_FAST, NULL);
+ mtx_lock_spin(&icu_lock);
INTREN(1 << apic_8254_intr);
+ mtx_unlock_spin(&icu_lock);
}
}
diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c
index 5e4dc61..1c70d86 100644
--- a/sys/kern/subr_witness.c
+++ b/sys/kern/subr_witness.c
@@ -215,10 +215,8 @@ static struct witness_order_list_entry order_lists[] = {
/*
* leaf locks
*/
+ { "icu", &lock_class_mtx_spin },
#ifdef SMP
-#ifdef __i386__
- { "imen", &lock_class_mtx_spin },
-#endif
{ "smp rendezvous", &lock_class_mtx_spin },
#endif
{ "clk", &lock_class_mtx_spin },
OpenPOWER on IntegriCloud