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.
This commit is contained in:
parent
f3c7fb1696
commit
98f9879242
@ -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);
|
||||
|
||||
/*
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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_ */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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_ */
|
||||
|
@ -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_ */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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 },
|
||||
|
Loading…
x
Reference in New Issue
Block a user