summaryrefslogtreecommitdiff
path: root/sys/arch/amd64
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2008-08-13 15:44:45 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2008-08-13 15:44:45 +0000
commit1c00afde35dfc3e0041cf90ffcff79c3f07ae7ac (patch)
tree7a10bb14c266b007f65c060ac33e4665bbba64ad /sys/arch/amd64
parent94345a96b6867ba746f48e4f629784c0e9764290 (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.
Diffstat (limited to 'sys/arch/amd64')
-rw-r--r--sys/arch/amd64/amd64/lapic.c27
-rw-r--r--sys/arch/amd64/include/specialreg.h6
2 files changed, 31 insertions, 2 deletions
diff --git a/sys/arch/amd64/amd64/lapic.c b/sys/arch/amd64/amd64/lapic.c
index 603cd4d5025..df55dc09ef5 100644
--- a/sys/arch/amd64/amd64/lapic.c
+++ b/sys/arch/amd64/amd64/lapic.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lapic.c,v 1.14 2008/06/26 05:42:09 ray Exp $ */
+/* $OpenBSD: lapic.c,v 1.15 2008/08/13 15:44:44 art Exp $ */
/* $NetBSD: lapic.c,v 1.2 2003/05/08 01:04:35 fvdl Exp $ */
/*-
@@ -157,6 +157,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/amd64/include/specialreg.h b/sys/arch/amd64/include/specialreg.h
index 0fc1094e793..f8d7448843e 100644
--- a/sys/arch/amd64/include/specialreg.h
+++ b/sys/arch/amd64/include/specialreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: specialreg.h,v 1.12 2008/06/13 00:00:45 jsg Exp $ */
+/* $OpenBSD: specialreg.h,v 1.13 2008/08/13 15:44:44 art Exp $ */
/* $NetBSD: specialreg.h,v 1.1 2003/04/26 18:39:48 fvdl Exp $ */
/* $NetBSD: x86/specialreg.h,v 1.2 2003/04/25 21:54:30 fvdl Exp $ */
@@ -289,6 +289,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.