Module Name: src Committed By: jruoho Date: Mon Feb 21 12:56:52 UTC 2011
Modified Files: src/sys/arch/x86/x86: coretemp.c Log Message: Add couple of additional CPU model checks for the undocumented Tj(max). To generate a diff of this commit: cvs rdiff -u -r1.19 -r1.20 src/sys/arch/x86/x86/coretemp.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/x86/x86/coretemp.c diff -u src/sys/arch/x86/x86/coretemp.c:1.19 src/sys/arch/x86/x86/coretemp.c:1.20 --- src/sys/arch/x86/x86/coretemp.c:1.19 Mon Feb 21 05:26:08 2011 +++ src/sys/arch/x86/x86/coretemp.c Mon Feb 21 12:56:52 2011 @@ -1,4 +1,34 @@ -/* $NetBSD: coretemp.c,v 1.19 2011/02/21 05:26:08 jruoho Exp $ */ +/* $NetBSD: coretemp.c,v 1.20 2011/02/21 12:56:52 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ /*- * Copyright (c) 2007 Juan Romero Pardines. @@ -30,13 +60,8 @@ * */ -/* - * Device driver for Intel's On Die thermal sensor via MSR. - * First introduced in Intel's Core line of processors. - */ - #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: coretemp.c,v 1.19 2011/02/21 05:26:08 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: coretemp.c,v 1.20 2011/02/21 12:56:52 jruoho Exp $"); #include <sys/param.h> #include <sys/device.h> @@ -75,11 +100,13 @@ #define MSR_THERM_INTR_TRIP2_VAL __BITS(16, 22) #define MSR_THERM_INTR_TRIP2 __BIT(23) +#define MSR_TEMP_TARGET_READOUT __BITS(16, 23) + static int coretemp_match(device_t, cfdata_t, void *); static void coretemp_attach(device_t, device_t, void *); static int coretemp_detach(device_t, int); static int coretemp_quirks(struct cpu_info *); -static void coretemp_ext_config(device_t); +static void coretemp_tjmax(device_t); static void coretemp_refresh(struct sysmon_envsys *, envsys_data_t *); static void coretemp_refresh_xcall(void *, void *); @@ -156,8 +183,7 @@ if (sysmon_envsys_register(sc->sc_sme) != 0) goto fail; - coretemp_ext_config(self); - + coretemp_tjmax(self); return; fail: @@ -179,11 +205,11 @@ static int coretemp_quirks(struct cpu_info *ci) { - uint32_t mask, model; + uint32_t model, stepping; uint64_t msr; - mask = ci->ci_signature & 0x0F; model = CPUID2MODEL(ci->ci_signature); + stepping = CPUID2STEPPING(ci->ci_signature); /* * Check if the MSR contains thermal @@ -204,7 +230,7 @@ * * Adapted from the Linux coretemp driver. */ - if (model == 0x0E && mask < 0x0C) { + if (model == 0x0E && stepping < 0x0C) { msr = rdmsr(MSR_BIOS_SIGN); msr = msr >> 32; @@ -217,34 +243,57 @@ } void -coretemp_ext_config(device_t self) +coretemp_tjmax(device_t self) { struct coretemp_softc *sc = device_private(self); struct cpu_info *ci = sc->sc_ci; - uint32_t emodel, mask, model; + uint32_t extmodel, model, stepping; uint64_t msr; - mask = ci->ci_signature & 0x0F; model = CPUID2MODEL(ci->ci_signature); - emodel = CPUID2EXTMODEL(ci->ci_signature); + extmodel = CPUID2EXTMODEL(ci->ci_signature); + stepping = CPUID2STEPPING(ci->ci_signature); + + sc->sc_tjmax = 100; /* - * 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_IA32_EXT_CONFIG is NOT safe on all CPUs + * The mobile Penryn family. */ - sc->sc_tjmax = 100; + if (model == 0x17 && stepping == 0x06) { + sc->sc_tjmax = 105; + return; + } - if ((model == 0x0F && mask >= 2) || (model == 0x0E && emodel != 1)) { + /* + * On some Core 2 CPUs, there is an undocumented + * MSR that tells if Tj(max) is 100 or 85. Note + * that MSR_IA32_EXT_CONFIG is not safe on all CPUs. + */ + if ((model == 0x0F && stepping >= 2) || + (model == 0x0E && extmodel != 1)) { msr = rdmsr(MSR_IA32_EXT_CONFIG); - if ((msr & __BIT(30)) != 0) + if ((msr & __BIT(30)) != 0) { sc->sc_tjmax = 85; + return; + } + } + + /* + * Attempt to get Tj(max) from IA32_TEMPERATURE_TARGET, + * but only consider the interval [70, 100] C as valid. + * It is not fully known which CPU models have the MSR. + */ + if (model == 0x0E) { + + msr = rdmsr(MSR_TEMPERATURE_TARGET); + msr = __SHIFTOUT(msr, MSR_TEMP_TARGET_READOUT); + + if (msr >= 70 && msr <= 100) { + sc->sc_tjmax = msr; + return; + } } }