diff options
author | fsmp <fsmp@FreeBSD.org> | 1997-07-28 03:59:54 +0000 |
---|---|---|
committer | fsmp <fsmp@FreeBSD.org> | 1997-07-28 03:59:54 +0000 |
commit | 97cf88454822faab01fb34a95617f90bf2ccfd10 (patch) | |
tree | f43ad826d8f8668bb45a7ea71fd291b87a690ff3 /sys/i386 | |
parent | 648817bf62e691487863de32a003dd42214a94e9 (diff) | |
download | FreeBSD-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.s | 54 | ||||
-rw-r--r-- | sys/i386/i386/mp_machdep.c | 8 | ||||
-rw-r--r-- | sys/i386/i386/mpapic.c | 15 | ||||
-rw-r--r-- | sys/i386/i386/mptable.c | 8 | ||||
-rw-r--r-- | sys/i386/include/mpapic.h | 7 | ||||
-rw-r--r-- | sys/i386/include/mptable.h | 8 | ||||
-rw-r--r-- | sys/i386/include/smp.h | 12 | ||||
-rw-r--r-- | sys/i386/isa/apic_vector.s | 54 |
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 |