summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/i386/i386/lapic.c27
-rw-r--r--sys/arch/i386/include/specialreg.h6
2 files changed, 31 insertions, 2 deletions
diff --git a/sys/arch/i386/i386/lapic.c b/sys/arch/i386/i386/lapic.c
index 5fcee282bd4..c193d26faac 100644
--- a/sys/arch/i386/i386/lapic.c
+++ b/sys/arch/i386/i386/lapic.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lapic.c,v 1.23 2008/06/26 05:42:10 ray Exp $ */
+/* $OpenBSD: lapic.c,v 1.24 2008/08/13 15:46:21 art Exp $ */
/* $NetBSD: lapic.c,v 1.1.2.8 2000/02/23 06:10:50 sommerfeld Exp $ */
/*-
@@ -130,6 +130,31 @@ lapic_set_lvt(void)
}
#endif
+ if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
+ /*
+ * Detect the presence of C1E capability mostly on latest
+ * dual-cores (or future) k8 family. This mis-feature renders
+ * the local APIC timer dead, so we disable it by reading
+ * the Interrupt Pending Message register and clearing both
+ * C1eOnCmpHalt (bit 28) and SmiOnCmpHalt (bit 27).
+ *
+ * Reference:
+ * "BIOS and Kernel Developer's Guide for AMD NPT
+ * Family 0Fh Processors"
+ * #32559 revision 3.00
+ */
+ if ((cpu_id & 0x00000f00) == 0x00000f00 &&
+ (cpu_id & 0x0fff0000) >= 0x00040000) {
+ uint64_t msr;
+
+ msr = rdmsr(MSR_INT_PEN_MSG);
+ if (msr & (IPM_C1E_CMP_HLT|IPM_SMI_CMP_HLT)) {
+ msr &= ~(IPM_C1E_CMP_HLT|IPM_SMI_CMP_HLT);
+ wrmsr(MSR_INT_PEN_MSG, msr);
+ }
+ }
+ }
+
for (i = 0; i < mp_nintrs; i++) {
mpi = &mp_intrs[i];
if (mpi->ioapic == NULL && (mpi->cpu_id == MPS_ALL_APICS
diff --git a/sys/arch/i386/include/specialreg.h b/sys/arch/i386/include/specialreg.h
index 3efc505c191..af65c0be9ea 100644
--- a/sys/arch/i386/include/specialreg.h
+++ b/sys/arch/i386/include/specialreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: specialreg.h,v 1.33 2008/06/13 00:00:45 jsg Exp $ */
+/* $OpenBSD: specialreg.h,v 1.34 2008/08/13 15:46:21 art Exp $ */
/* $NetBSD: specialreg.h,v 1.7 1994/10/27 04:16:26 cgd Exp $ */
/*-
@@ -274,6 +274,10 @@
#define MSR_FSBASE 0xc0000100 /* 64bit offset for fs: */
#define MSR_GSBASE 0xc0000101 /* 64bit offset for gs: */
#define MSR_KERNELGSBASE 0xc0000102 /* storage for swapgs ins */
+#define MSR_INT_PEN_MSG 0xc0010055 /* Interrupt pending message */
+
+#define IPM_C1E_CMP_HLT 0x10000000
+#define IPM_SMI_CMP_HLT 0x08000000
/*
* These require a 'passcode' for access. See cpufunc.h.