Author: delphij Date: Thu Jul 29 19:08:22 2010 New Revision: 210624 URL: http://svn.freebsd.org/changeset/base/210624
Log: Improve cputemp(4) driver wrt newer Intel processors, especially Xeon 5500/5600 series: - Utilize IA32_TEMPERATURE_TARGET, a.k.a. Tj(target) in place of Tj(max) when a sane value is available, as documented in Intel whitepaper "CPU Monitoring With DTS/PECI"; (By sane value we mean 70C - 100C for now); - Print the probe results when booting verbose; - Replace cpu_mask with cpu_stepping; - Use CPUID_* macros instead of rolling our own. Approved by: rpaulo MFC after: 1 month Modified: head/sys/amd64/include/specialreg.h head/sys/dev/coretemp/coretemp.c head/sys/i386/include/specialreg.h Modified: head/sys/amd64/include/specialreg.h ============================================================================== --- head/sys/amd64/include/specialreg.h Thu Jul 29 18:44:10 2010 (r210623) +++ head/sys/amd64/include/specialreg.h Thu Jul 29 19:08:22 2010 (r210624) @@ -258,6 +258,7 @@ #define MSR_THERM_INTERRUPT 0x19b #define MSR_THERM_STATUS 0x19c #define MSR_IA32_MISC_ENABLE 0x1a0 +#define MSR_IA32_TEMPERATURE_TARGET 0x1a2 #define MSR_DEBUGCTLMSR 0x1d9 #define MSR_LASTBRANCHFROMIP 0x1db #define MSR_LASTBRANCHTOIP 0x1dc Modified: head/sys/dev/coretemp/coretemp.c ============================================================================== --- head/sys/dev/coretemp/coretemp.c Thu Jul 29 18:44:10 2010 (r210623) +++ head/sys/dev/coretemp/coretemp.c Thu Jul 29 19:08:22 2010 (r210624) @@ -133,15 +133,13 @@ coretemp_attach(device_t dev) struct coretemp_softc *sc = device_get_softc(dev); device_t pdev; uint64_t msr; - int cpu_model; - int cpu_mask; + int cpu_model, cpu_stepping; + int ret, tjtarget; sc->sc_dev = dev; pdev = device_get_parent(dev); - cpu_model = (cpu_id >> 4) & 15; - /* extended model */ - cpu_model += ((cpu_id >> 16) & 0xf) << 4; - cpu_mask = cpu_id & 15; + cpu_model = CPUID_TO_MODEL(cpu_id); + cpu_stepping = cpu_id & CPUID_STEPPING; /* * Some CPUs, namely the PIII, don't have thermal sensors, but @@ -164,7 +162,7 @@ coretemp_attach(device_t dev) * * Adapted from the Linux coretemp driver. */ - if (cpu_model == 0xe && cpu_mask < 0xc) { + if (cpu_model == 0xe && cpu_stepping < 0xc) { msr = rdmsr(MSR_BIOS_SIGN); msr = msr >> 32; if (msr < 0x39) { @@ -174,20 +172,56 @@ coretemp_attach(device_t dev) } } #endif + /* - * On some Core 2 CPUs, there's an undocumented MSR that - * can tell us if Tj(max) is 100 or 85. - * - * The if-clause for CPUs having the MSR_IA32_EXT_CONFIG was adapted - * from the Linux coretemp driver. + * Use 100C as the initial value. */ sc->sc_tjmax = 100; - if ((cpu_model == 0xf && cpu_mask >= 2) || cpu_model == 0xe) { + + /* + * Attempt to get Tj(max) from MSR IA32_TEMPERATURE_TARGET. + * + * This method is described in Intel white paper + * "CPU Monitoring With DTS/PECI". (#322683) + */ + ret = rdmsr_safe(MSR_IA32_TEMPERATURE_TARGET, &msr); + if (ret == 0) { + tjtarget = (msr >> 16) & 0xff; + /* + * On earlier generation of processors, the value obtained + * from IA32_TEMPERATURE_TARGET register is an offset that + * needs to be summed with a model specific base. It is + * however not clear what these numbers are, with the + * publicly available documents from Intel. + * + * For now, we consider [70, 100]C range, as described in + * #322683, as "reasonable" and accept these values + * whenever the MSR is available for read, regardless the + * CPU model. + */ + if (tjtarget >= 70 && tjtarget <= 100) + sc->sc_tjmax = tjtarget; + else + device_printf(dev, "Tj(target) value %d does " + "not seem right.\n", tjtarget); + } + + if ((cpu_model == 0xf && cpu_stepping >= 2) || cpu_model == 0xe) { + /* + * On some Core 2 CPUs, there's an undocumented MSR that + * can tell us if Tj(max) is 100 or 85. + * + * The if-clause for CPUs having the MSR_IA32_EXT_CONFIG was adapted + * from the Linux coretemp driver. + */ msr = rdmsr(MSR_IA32_EXT_CONFIG); if (msr & (1 << 30)) sc->sc_tjmax = 85; } + if (bootverbose) + device_printf(dev, "Setting TjMax=%d\n", sc->sc_tjmax); + /* * Add the "temperature" MIB to dev.cpu.N. */ Modified: head/sys/i386/include/specialreg.h ============================================================================== --- head/sys/i386/include/specialreg.h Thu Jul 29 18:44:10 2010 (r210623) +++ head/sys/i386/include/specialreg.h Thu Jul 29 19:08:22 2010 (r210624) @@ -264,6 +264,7 @@ #define MSR_THERM_INTERRUPT 0x19b #define MSR_THERM_STATUS 0x19c #define MSR_IA32_MISC_ENABLE 0x1a0 +#define MSR_IA32_TEMPERATURE_TARGET 0x1a2 #define MSR_DEBUGCTLMSR 0x1d9 #define MSR_LASTBRANCHFROMIP 0x1db #define MSR_LASTBRANCHTOIP 0x1dc _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"