Date: Sat, 28 Aug 2010 00:48:40 +0000 (UTC) From: Xin LI <delphij@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r211914 - in stable/8/sys: amd64/include dev/coretemp i386/include Message-ID: <201008280048.o7S0mee2013338@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: delphij Date: Sat Aug 28 00:48:40 2010 New Revision: 211914 URL: http://svn.freebsd.org/changeset/base/211914 Log: MFC r210624 and r210833: 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. Catch known CPUs before using IA32_TEMPERATURE_TARGET. This way we would have an opportunity to hide the Tj(target) value doesn't seem right stuff if we know it's not working there. Add temperature value for Core2 Duo Extreme Mobile that I have access to. Modified: stable/8/sys/amd64/include/specialreg.h stable/8/sys/dev/coretemp/coretemp.c stable/8/sys/i386/include/specialreg.h Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) stable/8/sys/dev/xen/xenpci/ (props changed) Modified: stable/8/sys/amd64/include/specialreg.h ============================================================================== --- stable/8/sys/amd64/include/specialreg.h Sat Aug 28 00:34:22 2010 (r211913) +++ stable/8/sys/amd64/include/specialreg.h Sat Aug 28 00:48:40 2010 (r211914) @@ -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: stable/8/sys/dev/coretemp/coretemp.c ============================================================================== --- stable/8/sys/dev/coretemp/coretemp.c Sat Aug 28 00:34:22 2010 (r211913) +++ stable/8/sys/dev/coretemp/coretemp.c Sat Aug 28 00:48:40 2010 (r211914) @@ -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,68 @@ 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) { + + 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; + } else if (cpu_model == 0x17) { + switch (cpu_stepping) { + case 0x6: /* Mobile Core 2 Duo */ + sc->sc_tjmax = 104; + break; + default: /* Unknown stepping */ + break; + } + } else { + /* + * 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); + } else + device_printf(dev, "Can not get Tj(target) " + "from your CPU, using 100C.\n"); } + if (bootverbose) + device_printf(dev, "Setting TjMax=%d\n", sc->sc_tjmax); + /* * Add the "temperature" MIB to dev.cpu.N. */ Modified: stable/8/sys/i386/include/specialreg.h ============================================================================== --- stable/8/sys/i386/include/specialreg.h Sat Aug 28 00:34:22 2010 (r211913) +++ stable/8/sys/i386/include/specialreg.h Sat Aug 28 00:48:40 2010 (r211914) @@ -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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201008280048.o7S0mee2013338>