summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2005-11-21 18:39:17 +0000
committerjhb <jhb@FreeBSD.org>2005-11-21 18:39:17 +0000
commitf43bb7546346a694311becf1114bb2d99cb3739e (patch)
treea82283a0e20501a2111a6bf0073a58938c818b78 /sys/amd64
parent92462f1576f9f0523af96b1f5b45af5a353a12f9 (diff)
downloadFreeBSD-src-f43bb7546346a694311becf1114bb2d99cb3739e.zip
FreeBSD-src-f43bb7546346a694311becf1114bb2d99cb3739e.tar.gz
Expand the hack to mask the atpics if 'device atpic' is not in the kernel
during boot up. Now we do a full reset of the 8259As and setup a simple interrupt handler (we actually borrow the apic one that just does an immediate iret) to handle any spurious interrupts triggered by either chip. This should fix some folks that were getting a Trap 30 during bootup of certain SMP AMD systems. This might get pushed into the 6.0 branch as an errata. For now a suitable workaround is to add 'device atpic' to your kernel config. Tested by: scottl Helpful info from: dillon MFC after: 1 week
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/amd64/machdep.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index e336a31..0ee32f3 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -124,7 +124,9 @@ __FBSDID("$FreeBSD$");
#include <machine/smp.h>
#endif
+#include <dev/ic/i8259.h>
#include <amd64/isa/icu.h>
+#include <machine/apicvar.h>
#include <isa/isareg.h>
#include <isa/rtc.h>
@@ -1125,14 +1127,6 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
u_int64_t msr;
char *env;
-#ifdef DEV_ISA
- /* Preemptively mask the atpics and leave them shut down */
- outb(IO_ICU1 + ICU_IMR_OFFSET, 0xff);
- outb(IO_ICU2 + ICU_IMR_OFFSET, 0xff);
-#else
-#error "have you forgotten the isa device?";
-#endif
-
thread0.td_kstack = physfree + KERNBASE;
bzero((void *)thread0.td_kstack, KSTACK_PAGES * PAGE_SIZE);
physfree += KSTACK_PAGES * PAGE_SIZE;
@@ -1231,9 +1225,35 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
*/
cninit();
+#ifdef DEV_ISA
#ifdef DEV_ATPIC
elcr_probe();
atpic_startup();
+#else
+ /* Reset and mask the atpics and leave them shut down. */
+ outb(IO_ICU1, ICW1_RESET | ICW1_IC4);
+ outb(IO_ICU1 + ICU_IMR_OFFSET, IDT_IO_INTS);
+ outb(IO_ICU1 + ICU_IMR_OFFSET, 1 << 2);
+ outb(IO_ICU1 + ICU_IMR_OFFSET, ICW4_8086);
+ outb(IO_ICU1 + ICU_IMR_OFFSET, 0xff);
+ outb(IO_ICU1, OCW3_SEL | OCW3_RR);
+
+ outb(IO_ICU2, ICW1_RESET | ICW1_IC4);
+ outb(IO_ICU2 + ICU_IMR_OFFSET, IDT_IO_INTS + 8);
+ outb(IO_ICU2 + ICU_IMR_OFFSET, 2);
+ outb(IO_ICU2 + ICU_IMR_OFFSET, ICW4_8086);
+ outb(IO_ICU2 + ICU_IMR_OFFSET, 0xff);
+ outb(IO_ICU2, OCW3_SEL | OCW3_RR);
+
+ /*
+ * Point the ICU spurious interrupt vectors at the APIC spurious
+ * interrupt handler.
+ */
+ setidt(IDT_IO_INTS + 7, IDTVEC(spuriousint), SDT_SYSIGT, SEL_KPL, 0);
+ setidt(IDT_IO_INTS + 15, IDTVEC(spuriousint), SDT_SYSIGT, SEL_KPL, 0);
+#endif
+#else
+#error "have you forgotten the isa device?";
#endif
kdb_init();
OpenPOWER on IntegriCloud