Subject: port-amd64/36633: Enhanced Speedstep is not enabled for Intel EM64T CPUs
To: None <port-amd64-maintainer@netbsd.org, gnats-admin@netbsd.org,>
From: Pierre Pronchery <khorben@defora.org>
List: netbsd-bugs
Date: 07/11/2007 15:50:00
>Number: 36633
>Category: port-amd64
>Synopsis: Enhanced Speedstep is not enabled for Intel EM64T CPUs
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: port-amd64-maintainer
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Jul 11 15:50:00 +0000 2007
>Originator: Pierre Pronchery
>Release: NetBSD 4.0_BETA2
>Organization:
khorben
>Environment:
System: NetBSD syn.defora.rom 4.0_BETA2 NetBSD 4.0_BETA2 (GENERIC.MP) #26: Tue Jul 10 14:44:16 CEST 2007 khorben@syn.defora.rom:/usr/obj/sys/arch/amd64/compile/GENERIC.MP amd64
Architecture: x86_64
Machine: amd64
>Description:
Generally speaking, the amd64 port's default kernel is not very friendly
to laptops. Enhanced Speedstep in particular is not supported for Intel
machines featuring this instruction set (eg Core 2 Duo "Merom").
>How-To-Repeat:
Boot an amd64 kernel on an EM64T machine.
>Fix:
The following patch works for me (Intel Core 2 Duo). It applies against
4.0_BETA2. It will certainly require additional cosmetics (estd.c moved
to arch/x86, etc).
It also contains my GENERIC.local file, which could be made separate in
a GENERIC_LAPTOP file.
Index: arch/amd64/amd64/identcpu.c
===================================================================
RCS file: /cvsroot/src/sys/arch/amd64/amd64/identcpu.c,v
retrieving revision 1.7.2.2
diff -u -r1.7.2.2 identcpu.c
--- arch/amd64/amd64/identcpu.c 15 Jun 2007 10:27:36 -0000 1.7.2.2
+++ arch/amd64/amd64/identcpu.c 11 Jul 2007 11:03:46 -0000
@@ -52,6 +52,104 @@
/* sysctl wants this. */
char cpu_model[48];
+#ifdef ENHANCED_SPEEDSTEP
+void p3_get_bus_clock(struct cpu_info *ci);
+void p3_get_bus_clock(struct cpu_info *ci)
+{
+ uint64_t msr;
+ int model, bus;
+ char *cpuname = ci->ci_dev->dv_xname;
+
+ model = (ci->ci_signature >> 4) & 15;
+ switch (model) {
+ case 0x9: /* Pentium M (130 nm, Banias) */
+ bus_clock = 10000;
+ break;
+ case 0xd: /* Pentium M (90 nm, Dothan) */
+ msr = rdmsr(MSR_FSB_FREQ);
+ bus = (msr >> 0) & 0x7;
+ switch (bus) {
+ case 0:
+ bus_clock = 10000;
+ break;
+ case 1:
+ bus_clock = 13333;
+ break;
+ default:
+ aprint_debug("%s: unknown Pentium M FSB_FREQ "
+ "value %d", cpuname, bus);
+ goto print_msr;
+ }
+ break;
+ case 0xe: /* Core Duo/Solo */
+ case 0xf: /* Core Xeon */
+ msr = rdmsr(MSR_FSB_FREQ);
+ bus = (msr >> 0) & 0x7;
+ switch (bus) {
+ case 5:
+ bus_clock = 10000;
+ break;
+ case 1:
+ bus_clock = 13333;
+ break;
+ case 3:
+ bus_clock = 16667;
+ break;
+ case 2:
+ bus_clock = 20000;
+ break;
+ case 0:
+ bus_clock = 26667;
+ break;
+ case 4:
+ bus_clock = 33333;
+ break;
+ default:
+ aprint_debug("%s: unknown Core FSB_FREQ value %d",
+ cpuname, bus);
+ goto print_msr;
+ }
+ break;
+ case 0x1: /* Pentium Pro, model 1 */
+ case 0x3: /* Pentium II, model 3 */
+ case 0x5: /* Pentium II, II Xeon, Celeron, model 5 */
+ case 0x6: /* Celeron, model 6 */
+ case 0x7: /* Pentium III, III Xeon, model 7 */
+ case 0x8: /* Pentium III, III Xeon, Celeron, model 8 */
+ case 0xa: /* Pentium III Xeon, model A */
+ case 0xb: /* Pentium III, model B */
+ msr = rdmsr(MSR_EBL_CR_POWERON);
+ bus = (msr >> 18) & 0x3;
+ switch (bus) {
+ case 0:
+ bus_clock = 6666;
+ break;
+ case 1:
+ bus_clock = 13333;
+ break;
+ case 2:
+ bus_clock = 10000;
+ break;
+ default:
+ aprint_debug("%s: unknown i686 EBL_CR_POWERON "
+ "value %d ", cpuname, bus);
+ goto print_msr;
+ }
+ break;
+ default:
+ aprint_debug("%s: unknown i686 model %d, can't get bus clock",
+ cpuname, model);
+print_msr:
+ /*
+ * Show the EBL_CR_POWERON MSR, so we'll at least have
+ * some extra information, such as clock ratio, etc.
+ */
+ aprint_debug(" (0x%lx)\n", rdmsr(MSR_EBL_CR_POWERON));
+ break;
+ }
+}
+#endif
+
void
identifycpu(struct cpu_info *ci)
{
@@ -139,6 +237,24 @@
x86_print_cacheinfo(ci);
+#ifdef ENHANCED_SPEEDSTEP
+ aprint_verbose("%s: probing Enhanced SpeedStep\n",
+ ci->ci_dev->dv_xname);
+ if (ci->ci_feature2_flags & CPUID2_EST) {
+ if (rdmsr(MSR_MISC_ENABLE) & (1 << 16))
+ {
+ p3_get_bus_clock(ci);
+ est_init(CPUVENDOR_INTEL);
+ }
+ else
+ aprint_verbose("%s: Enhanced SpeedStep disabled by BIOS\n",
+ ci->ci_dev->dv_xname);
+ }
+ else
+ aprint_verbose("%s: Enhanced SpeedStep not found\n",
+ ci->ci_dev->dv_xname);
+#endif /* ENHANCED_SPEEDSTEP */
+
#ifdef POWERNOW_K8
if (CPUID2FAMILY(ci->ci_signature) == 15 &&
(cpu_model[0] == 'A' || cpu_model[0] == 'O') &&
Index: arch/amd64/conf/GENERIC.local
===================================================================
RCS file: /cvsroot/src/sys/arch/amd64/conf/GENERIC.local,v
retrieving revision 1.1
diff -u -r1.1 GENERIC.local
--- arch/amd64/conf/GENERIC.local 26 Apr 2003 18:39:34 -0000 1.1
+++ arch/amd64/conf/GENERIC.local 11 Jul 2007 11:03:46 -0000
@@ -3,3 +3,46 @@
# GENERIC.local -- local additions to the GENERIC configuration
#
+acpiacad* at acpi?
+acpibat* at acpi?
+acpibut* at acpi?
+acpiec* at acpi?
+acpilid* at acpi?
+acpitz* at acpi?
+
+com* at acpi?
+fdc* at acpi?
+joy* at acpi?
+lpt* at acpi?
+mpu* at acpi?
+pckbc* at acpi?
+attimer* at acpi?
+pcppi* at acpi?
+ug* at acpi?
+wss* at acpi?
+
+#agp* at pchb?
+
+cbb* at pci? dev ? function ?
+cardslot* at cbb?
+
+cardbus* at cardslot?
+pcmcia* at cardslot?
+
+com* at pcmcia? function ?
+
+com* at cardbus? function ?
+
+wdc* at pcmcia? function ?
+
+wi* at pcmcia? function ?
+
+ehci* at cardbus? function ?
+ohci* at cardbus? function ?
+
+cdce* at uhub? port ?
+wpi* at pci? dev ? function ?
+
+options ENHANCED_SPEEDSTEP
+
+pseudo-device cgd 4 # cryptographic disk devices
Index: arch/amd64/conf/files.amd64
===================================================================
RCS file: /cvsroot/src/sys/arch/amd64/conf/files.amd64,v
retrieving revision 1.29
diff -u -r1.29 files.amd64
--- arch/amd64/conf/files.amd64 10 Sep 2006 19:50:48 -0000 1.29
+++ arch/amd64/conf/files.amd64 11 Jul 2007 11:03:47 -0000
@@ -201,4 +201,8 @@
include "dev/acpi/files.acpi"
file arch/amd64/acpi/acpi_wakeup.c acpi
+# Enhanced SpeedStep
+file arch/i386/i386/est.c enhanced_speedstep
+defflag opt_est.h EST_FREQ_USERWRITE
+
include "arch/amd64/conf/majors.amd64"
Index: arch/amd64/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/amd64/include/cpu.h,v
retrieving revision 1.12.8.1
diff -u -r1.12.8.1 cpu.h
--- arch/amd64/include/cpu.h 5 Jun 2007 20:28:11 -0000 1.12.8.1
+++ arch/amd64/include/cpu.h 11 Jul 2007 11:03:47 -0000
@@ -244,6 +244,7 @@
/*
* pull in #defines for kinds of processors
*/
+#include <machine/cputypes.h>
extern int biosbasemem;
extern int biosextmem;
@@ -255,6 +256,9 @@
/* identcpu.c */
+#ifdef ENHANCED_SPEEDSTEP
+extern int bus_clock;
+#endif
void identifycpu __P((struct cpu_info *));
void cpu_probe_features __P((struct cpu_info *));
@@ -302,6 +306,9 @@
/* powernow_k8.c */
void k8_powernow_init(void);
+/* est.c */
+void est_init(int);
+
#endif /* _KERNEL */
#include <machine/psl.h>
Index: arch/i386/i386/est.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/i386/Attic/est.c,v
retrieving revision 1.31.2.2
diff -u -r1.31.2.2 est.c
--- arch/i386/i386/est.c 20 Apr 2007 20:31:25 -0000 1.31.2.2
+++ arch/i386/i386/est.c 11 Jul 2007 11:04:06 -0000
@@ -952,7 +952,7 @@
if (idhi == 0 || idlo == 0 || cur == 0 ||
((cur >> 8) & 0xff) < ((idlo >> 8) & 0xff) ||
((cur >> 8) & 0xff) > ((idhi >> 8) & 0xff)) {
- aprint_debug("%s: strange msr value 0x%016llx\n", __func__, msr);
+ aprint_debug("%s: strange msr value 0x%016lx\n", __func__, msr);
return;
}