summaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
authorfsmp <fsmp@FreeBSD.org>1997-07-28 03:59:54 +0000
committerfsmp <fsmp@FreeBSD.org>1997-07-28 03:59:54 +0000
commit97cf88454822faab01fb34a95617f90bf2ccfd10 (patch)
treef43ad826d8f8668bb45a7ea71fd291b87a690ff3 /sys/i386
parent648817bf62e691487863de32a003dd42214a94e9 (diff)
downloadFreeBSD-src-97cf88454822faab01fb34a95617f90bf2ccfd10.zip
FreeBSD-src-97cf88454822faab01fb34a95617f90bf2ccfd10.tar.gz
Modified the PEND_INTS algorithm to fix the ISA INT loss problem.
Noticed by: dave adkins <adkin003@gold.tc.umn.edu> and others.
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/i386/apic_vector.s54
-rw-r--r--sys/i386/i386/mp_machdep.c8
-rw-r--r--sys/i386/i386/mpapic.c15
-rw-r--r--sys/i386/i386/mptable.c8
-rw-r--r--sys/i386/include/mpapic.h7
-rw-r--r--sys/i386/include/mptable.h8
-rw-r--r--sys/i386/include/smp.h12
-rw-r--r--sys/i386/isa/apic_vector.s54
8 files changed, 141 insertions, 25 deletions
diff --git a/sys/i386/i386/apic_vector.s b/sys/i386/i386/apic_vector.s
index 00f6b8d..dfc2d97 100644
--- a/sys/i386/i386/apic_vector.s
+++ b/sys/i386/i386/apic_vector.s
@@ -1,10 +1,11 @@
/*
* from: vector.s, 386BSD 0.1 unknown origin
- * $Id: apic_vector.s,v 1.15 1997/07/25 22:20:11 smp Exp smp $
+ * $Id: apic_vector.s,v 1.17 1997/07/28 03:51:01 smp Exp smp $
*/
-#include <machine/smptests.h> /** various counters */
+#include <machine/smp.h>
+#include <machine/smptests.h> /** PEND_INTS, various counters */
#include "i386/isa/intr_machdep.h"
/* convert an absolute IRQ# into a bitmask */
@@ -19,6 +20,8 @@
#ifdef PEND_INTS
+#ifdef FIRST_TRY
+
#define MAYBE_MASK_IRQ(irq_num) \
lock ; /* MP-safe */ \
btsl $(irq_num),iactive ; /* lazy masking */ \
@@ -46,6 +49,47 @@
testl %eax, %eax ; \
jz 7b /* can't enter kernel */
+#else /** FIRST_TRY */
+
+/*
+ * the 1st version fails because masked edge-triggered INTs are lost
+ * by the IO APIC. This version tests 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, and the EOI cycle would allow
+ * recursive INTs to occur.
+ */
+#define MAYBE_MASK_IRQ(irq_num) \
+ lock ; /* MP-safe */ \
+ btsl $(irq_num),iactive ; /* lazy masking */ \
+ jc 6f ; /* already active */ \
+ call _try_mplock ; /* try to get lock */ \
+ testl %eax, %eax ; /* did we get it? */ \
+ jnz 8f ; /* yes, enter kernel */ \
+6: ; /* active or locked */ \
+ IMASK_LOCK ; /* into critical reg */ \
+ testl $IRQ_BIT(irq_num),_apic_pin_trigger ; \
+ jz 7f ; /* edge, don't mask */ \
+ orl $IRQ_BIT(irq_num),_apic_imen ; /* set the mask bit */ \
+ movl _ioapic,%ecx ; /* ioapic[0] addr */ \
+ movl $REDTBL_IDX(irq_num),(%ecx) ; /* write the index */ \
+ movl IOAPIC_WINDOW(%ecx),%eax ; /* current value */ \
+ orl $IOART_INTMASK,%eax ; /* set the mask */ \
+ movl %eax,IOAPIC_WINDOW(%ecx) ; /* new value */ \
+7: ; \
+ orl $IRQ_BIT(irq_num), _ipending ; /* set _ipending bit */ \
+ IMASK_UNLOCK ; /* exit critical reg */ \
+ movl $0, lapic_eoi ; /* do the EOI */ \
+ popl %es ; \
+ popl %ds ; \
+ popal ; \
+ addl $4+4,%esp ; \
+ iret ; \
+; \
+ ALIGN_TEXT ; \
+8:
+
+#endif /** FIRST_TRY */
+
#else /* PEND_INTS */
#define MAYBE_MASK_IRQ(irq_num) \
@@ -408,6 +452,12 @@ _cshits:
.space (NCPU * 4), 0
#endif /* COUNT_CSHITS */
+#ifdef PEND_INTS
+ .globl _apic_pin_trigger
+_apic_pin_trigger:
+ .space (NAPIC * 4), 0
+#endif /* PEND_INTS */
+
/*
* Interrupt counters and names. The format of these and the label names
diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c
index daf3033..ff0390a 100644
--- a/sys/i386/i386/mp_machdep.c
+++ b/sys/i386/i386/mp_machdep.c
@@ -22,7 +22,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: mp_machdep.c,v 1.36 1997/07/23 20:47:19 fsmp Exp $
+ * $Id: mp_machdep.c,v 1.22 1997/07/28 03:39:06 smp Exp smp $
*/
#include "opt_smp.h"
@@ -1380,11 +1380,11 @@ default_mp_table(int type)
/* general cases from MP v1.4, table 5-2 */
for (pin = 0; pin < 16; ++pin) {
io_apic_ints[pin].int_type = 0;
- io_apic_ints[pin].int_flags = 0x05; /* edge-triggered/active-hi */
+ io_apic_ints[pin].int_flags = 0x05; /* edge/active-hi */
io_apic_ints[pin].src_bus_id = 0;
- io_apic_ints[pin].src_bus_irq = pin; /* IRQ2 is caught below */
+ io_apic_ints[pin].src_bus_irq = pin; /* IRQ2 caught below */
io_apic_ints[pin].dst_apic_id = io_apic_id;
- io_apic_ints[pin].dst_apic_int = pin; /* 1-to-1 correspondence */
+ io_apic_ints[pin].dst_apic_int = pin; /* 1-to-1 */
}
/* special cases from MP v1.4, table 5-2 */
diff --git a/sys/i386/i386/mpapic.c b/sys/i386/i386/mpapic.c
index af9ba12..34060ba 100644
--- a/sys/i386/i386/mpapic.c
+++ b/sys/i386/i386/mpapic.c
@@ -22,7 +22,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: mpapic.c,v 1.22 1997/07/23 20:47:19 fsmp Exp $
+ * $Id: mpapic.c,v 1.25 1997/07/28 03:39:06 smp Exp smp $
*/
#include "opt_smp.h"
@@ -30,7 +30,7 @@
#include <sys/types.h>
#include <sys/systm.h>
-#include <machine/smptests.h> /** TEST_LOPRIO, TEST_TEST1 */
+#include <machine/smptests.h> /** TEST_LOPRIO, PEND_INTS, TEST_TEST1 */
#include <machine/smp.h>
#include <machine/mpapic.h>
#include <machine/segments.h>
@@ -166,6 +166,9 @@ static void polarity __P((int apic, int pin, u_int32_t * flags, int level));
/*
* Setup the IO APIC.
*/
+#if defined(PEND_INTS)
+extern int apic_pin_trigger[]; /* 'opaque' */
+#endif /* PEND_INTS */
int
io_apic_setup(int apic)
{
@@ -182,6 +185,10 @@ io_apic_setup(int apic)
target = boot_cpu_id << 24;
#endif /* TEST_LOPRIO */
+#if defined(PEND_INTS)
+ apic_pin_trigger[apic] = 0; /* default to edge-triggered */
+#endif /* PEND_INTS */
+
if (apic == 0) {
maxpin = REDIRCNT_IOAPIC(apic); /* pins-1 in APIC */
for (pin = 0; pin < maxpin; ++pin) {
@@ -206,6 +213,10 @@ io_apic_setup(int apic)
else {
flags = DEFAULT_FLAGS;
level = trigger(apic, pin, &flags);
+#if defined(PEND_INTS)
+ if (level == 1)
+ apic_pin_trigger[apic] |= (1 << pin);
+#endif /* PEND_INTS */
polarity(apic, pin, &flags, level);
}
diff --git a/sys/i386/i386/mptable.c b/sys/i386/i386/mptable.c
index daf3033..ff0390a 100644
--- a/sys/i386/i386/mptable.c
+++ b/sys/i386/i386/mptable.c
@@ -22,7 +22,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: mp_machdep.c,v 1.36 1997/07/23 20:47:19 fsmp Exp $
+ * $Id: mp_machdep.c,v 1.22 1997/07/28 03:39:06 smp Exp smp $
*/
#include "opt_smp.h"
@@ -1380,11 +1380,11 @@ default_mp_table(int type)
/* general cases from MP v1.4, table 5-2 */
for (pin = 0; pin < 16; ++pin) {
io_apic_ints[pin].int_type = 0;
- io_apic_ints[pin].int_flags = 0x05; /* edge-triggered/active-hi */
+ io_apic_ints[pin].int_flags = 0x05; /* edge/active-hi */
io_apic_ints[pin].src_bus_id = 0;
- io_apic_ints[pin].src_bus_irq = pin; /* IRQ2 is caught below */
+ io_apic_ints[pin].src_bus_irq = pin; /* IRQ2 caught below */
io_apic_ints[pin].dst_apic_id = io_apic_id;
- io_apic_ints[pin].dst_apic_int = pin; /* 1-to-1 correspondence */
+ io_apic_ints[pin].dst_apic_int = pin; /* 1-to-1 */
}
/* special cases from MP v1.4, table 5-2 */
diff --git a/sys/i386/include/mpapic.h b/sys/i386/include/mpapic.h
index d984a3b..09466a8 100644
--- a/sys/i386/include/mpapic.h
+++ b/sys/i386/include/mpapic.h
@@ -22,7 +22,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: mpapic.h,v 1.3 1997/07/22 18:31:51 smp Exp smp $
+ * $Id: mpapic.h,v 1.4 1997/07/28 03:40:09 smp Exp smp $
*/
#ifndef _MACHINE_MPAPIC_H_
@@ -36,11 +36,6 @@
# define NBUS 4
#endif /* NBUS */
-/* number of IO APICs */
-# if !defined(NAPIC)
-# define NAPIC 1
-# endif /* NAPIC */
-
/* total number of APIC INTs, including SHARED INTs */
#if !defined(NINTR)
#define NINTR 48
diff --git a/sys/i386/include/mptable.h b/sys/i386/include/mptable.h
index daf3033..ff0390a 100644
--- a/sys/i386/include/mptable.h
+++ b/sys/i386/include/mptable.h
@@ -22,7 +22,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: mp_machdep.c,v 1.36 1997/07/23 20:47:19 fsmp Exp $
+ * $Id: mp_machdep.c,v 1.22 1997/07/28 03:39:06 smp Exp smp $
*/
#include "opt_smp.h"
@@ -1380,11 +1380,11 @@ default_mp_table(int type)
/* general cases from MP v1.4, table 5-2 */
for (pin = 0; pin < 16; ++pin) {
io_apic_ints[pin].int_type = 0;
- io_apic_ints[pin].int_flags = 0x05; /* edge-triggered/active-hi */
+ io_apic_ints[pin].int_flags = 0x05; /* edge/active-hi */
io_apic_ints[pin].src_bus_id = 0;
- io_apic_ints[pin].src_bus_irq = pin; /* IRQ2 is caught below */
+ io_apic_ints[pin].src_bus_irq = pin; /* IRQ2 caught below */
io_apic_ints[pin].dst_apic_id = io_apic_id;
- io_apic_ints[pin].dst_apic_int = pin; /* 1-to-1 correspondence */
+ io_apic_ints[pin].dst_apic_int = pin; /* 1-to-1 */
}
/* special cases from MP v1.4, table 5-2 */
diff --git a/sys/i386/include/smp.h b/sys/i386/include/smp.h
index d798417..9dcefd2 100644
--- a/sys/i386/include/smp.h
+++ b/sys/i386/include/smp.h
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: smp.h,v 1.20 1997/07/23 20:42:16 fsmp Exp $
+ * $Id: smp.h,v 1.17 1997/07/28 03:40:09 smp Exp smp $
*
*/
@@ -19,12 +19,21 @@
# error APIC_IO required for SMP, add "options APIC_IO" to your config file.
#endif /* SMP && !APIC_IO */
+/* Number of CPUs. */
#if defined(SMP) && !defined(NCPU)
# define NCPU 2
#endif /* SMP && NCPU */
+/* Number of IO APICs. */
+#if defined(APIC_IO) && !defined(NAPIC)
+# define NAPIC 1
+#endif /* SMP && NAPIC */
+
+
#if defined(SMP) || defined(APIC_IO)
+#ifndef LOCORE
+
/*
* For sending values to POST displays.
* XXX FIXME: where does this really belong, isa.h/isa.c perhaps?
@@ -158,6 +167,7 @@ extern volatile u_int cpuid;
extern volatile u_int cpu_lockid;
extern volatile u_int other_cpus;
+#endif /* !LOCORE */
#endif /* SMP || APIC_IO */
#endif /* KERNEL */
#endif /* _MACHINE_SMP_H_ */
diff --git a/sys/i386/isa/apic_vector.s b/sys/i386/isa/apic_vector.s
index 00f6b8d..dfc2d97 100644
--- a/sys/i386/isa/apic_vector.s
+++ b/sys/i386/isa/apic_vector.s
@@ -1,10 +1,11 @@
/*
* from: vector.s, 386BSD 0.1 unknown origin
- * $Id: apic_vector.s,v 1.15 1997/07/25 22:20:11 smp Exp smp $
+ * $Id: apic_vector.s,v 1.17 1997/07/28 03:51:01 smp Exp smp $
*/
-#include <machine/smptests.h> /** various counters */
+#include <machine/smp.h>
+#include <machine/smptests.h> /** PEND_INTS, various counters */
#include "i386/isa/intr_machdep.h"
/* convert an absolute IRQ# into a bitmask */
@@ -19,6 +20,8 @@
#ifdef PEND_INTS
+#ifdef FIRST_TRY
+
#define MAYBE_MASK_IRQ(irq_num) \
lock ; /* MP-safe */ \
btsl $(irq_num),iactive ; /* lazy masking */ \
@@ -46,6 +49,47 @@
testl %eax, %eax ; \
jz 7b /* can't enter kernel */
+#else /** FIRST_TRY */
+
+/*
+ * the 1st version fails because masked edge-triggered INTs are lost
+ * by the IO APIC. This version tests 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, and the EOI cycle would allow
+ * recursive INTs to occur.
+ */
+#define MAYBE_MASK_IRQ(irq_num) \
+ lock ; /* MP-safe */ \
+ btsl $(irq_num),iactive ; /* lazy masking */ \
+ jc 6f ; /* already active */ \
+ call _try_mplock ; /* try to get lock */ \
+ testl %eax, %eax ; /* did we get it? */ \
+ jnz 8f ; /* yes, enter kernel */ \
+6: ; /* active or locked */ \
+ IMASK_LOCK ; /* into critical reg */ \
+ testl $IRQ_BIT(irq_num),_apic_pin_trigger ; \
+ jz 7f ; /* edge, don't mask */ \
+ orl $IRQ_BIT(irq_num),_apic_imen ; /* set the mask bit */ \
+ movl _ioapic,%ecx ; /* ioapic[0] addr */ \
+ movl $REDTBL_IDX(irq_num),(%ecx) ; /* write the index */ \
+ movl IOAPIC_WINDOW(%ecx),%eax ; /* current value */ \
+ orl $IOART_INTMASK,%eax ; /* set the mask */ \
+ movl %eax,IOAPIC_WINDOW(%ecx) ; /* new value */ \
+7: ; \
+ orl $IRQ_BIT(irq_num), _ipending ; /* set _ipending bit */ \
+ IMASK_UNLOCK ; /* exit critical reg */ \
+ movl $0, lapic_eoi ; /* do the EOI */ \
+ popl %es ; \
+ popl %ds ; \
+ popal ; \
+ addl $4+4,%esp ; \
+ iret ; \
+; \
+ ALIGN_TEXT ; \
+8:
+
+#endif /** FIRST_TRY */
+
#else /* PEND_INTS */
#define MAYBE_MASK_IRQ(irq_num) \
@@ -408,6 +452,12 @@ _cshits:
.space (NCPU * 4), 0
#endif /* COUNT_CSHITS */
+#ifdef PEND_INTS
+ .globl _apic_pin_trigger
+_apic_pin_trigger:
+ .space (NAPIC * 4), 0
+#endif /* PEND_INTS */
+
/*
* Interrupt counters and names. The format of these and the label names
OpenPOWER on IntegriCloud