summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2008-08-13 15:46:22 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2008-08-13 15:46:22 +0000
commit77b098353d39395969c7f9f95b90d104a884ca8a (patch)
treee468ebd24157a14e712ea7daa362853c0b275e50
parent7c0b6e385e1a3db611671cc0e443279a4d50f2b2 (diff)
Disable the fantastics mis-feature on some newer Turion CPUs called C1E.
This "power saving" disables the apic when both cpu cores hit the hlt instruction which kills our timer. From FreeBSD. (poked by kettenis)
-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.