diff options
author | jhb <jhb@FreeBSD.org> | 2001-12-20 23:48:31 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2001-12-20 23:48:31 +0000 |
commit | 2463f40fc340e69b97e1ba3f1a7db47384b50a83 (patch) | |
tree | dec76d77f99795635c90df0631ffc2beb333b91b /sys/amd64/isa | |
parent | 7a0109b5c0a87d4cff83c1923789cf9c5b38126a (diff) | |
download | FreeBSD-src-2463f40fc340e69b97e1ba3f1a7db47384b50a83.zip FreeBSD-src-2463f40fc340e69b97e1ba3f1a7db47384b50a83.tar.gz |
Introduce a standard name for the lock protecting an interrupt controller
and it's associated state variables: icu_lock with the name "icu". This
renames the imen_mtx for x86 SMP, but also uses the lock to protect
access to the 8259 PIC on x86 UP. This also adds an appropriate lock to
the various Alpha chipsets which fixes problems with Alpha SMP machines
dropping interrupts with an SMP kernel.
Diffstat (limited to 'sys/amd64/isa')
-rw-r--r-- | sys/amd64/isa/clock.c | 10 | ||||
-rw-r--r-- | sys/amd64/isa/intr_machdep.c | 27 | ||||
-rw-r--r-- | sys/amd64/isa/intr_machdep.h | 11 | ||||
-rw-r--r-- | sys/amd64/isa/nmi.c | 27 | ||||
-rw-r--r-- | sys/amd64/isa/npx.c | 3 | ||||
-rw-r--r-- | sys/amd64/isa/vector.S | 1 | ||||
-rw-r--r-- | sys/amd64/isa/vector.s | 1 |
7 files changed, 55 insertions, 25 deletions
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 |