Sat Jul 29 11:01:15 2023 UTC ()
Pull up following revision(s) (requested by msaitoh in ticket #254):

	sys/arch/x86/x86/coretemp.c: revision 1.38-1.39 (patch)

coretemp(4): Change limits of Tjmax.
 - Change the lower limit from 70 to 60. At least, some BIOSes can change
   the value down to 62.
 - Change the upper limit from 110 to 120. At least, some BIOSes can change
   the value up to 115.
 - Print error message when rdmsr(TEMPERATURE_TARGET) failed.
 - When Tjmax exceeded the limit, print warning message and use the value
   as it is.
 - KNF.


(martin)
diff -r1.36.4.1 -r1.36.4.2 src/sys/arch/x86/x86/coretemp.c

cvs diff -r1.36.4.1 -r1.36.4.2 src/sys/arch/x86/x86/coretemp.c (expand / switch to unified diff)

--- src/sys/arch/x86/x86/coretemp.c 2020/07/15 14:02:36 1.36.4.1
+++ src/sys/arch/x86/x86/coretemp.c 2023/07/29 11:01:14 1.36.4.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: coretemp.c,v 1.36.4.1 2020/07/15 14:02:36 martin Exp $ */ 1/* $NetBSD: coretemp.c,v 1.36.4.2 2023/07/29 11:01:14 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2011 The NetBSD Foundation, Inc. 4 * Copyright (c) 2011 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jukka Ruohonen. 8 * by Jukka Ruohonen.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 13 *
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -51,27 +51,27 @@ @@ -51,27 +51,27 @@
51 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 51 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
52 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 52 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
53 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 53 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
55 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 55 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
56 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 56 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
57 * POSSIBILITY OF SUCH DAMAGE. 57 * POSSIBILITY OF SUCH DAMAGE.
58 * 58 *
59 * $FreeBSD: src/sys/dev/coretemp/coretemp.c,v 1.4 2007/10/15 20:00:21 netchild Exp $ 59 * $FreeBSD: src/sys/dev/coretemp/coretemp.c,v 1.4 2007/10/15 20:00:21 netchild Exp $
60 * 60 *
61 */ 61 */
62 62
63#include <sys/cdefs.h> 63#include <sys/cdefs.h>
64__KERNEL_RCSID(0, "$NetBSD: coretemp.c,v 1.36.4.1 2020/07/15 14:02:36 martin Exp $"); 64__KERNEL_RCSID(0, "$NetBSD: coretemp.c,v 1.36.4.2 2023/07/29 11:01:14 martin Exp $");
65 65
66#include <sys/param.h> 66#include <sys/param.h>
67#include <sys/device.h> 67#include <sys/device.h>
68#include <sys/cpu.h> 68#include <sys/cpu.h>
69#include <sys/module.h> 69#include <sys/module.h>
70#include <sys/xcall.h> 70#include <sys/xcall.h>
71 71
72#include <dev/sysmon/sysmonvar.h> 72#include <dev/sysmon/sysmonvar.h>
73 73
74#include <machine/cpuvar.h> 74#include <machine/cpuvar.h>
75#include <machine/cpufunc.h> 75#include <machine/cpufunc.h>
76#include <machine/cputypes.h> 76#include <machine/cputypes.h>
77#include <machine/specialreg.h> 77#include <machine/specialreg.h>
@@ -92,26 +92,30 @@ __KERNEL_RCSID(0, "$NetBSD: coretemp.c,v @@ -92,26 +92,30 @@ __KERNEL_RCSID(0, "$NetBSD: coretemp.c,v
92 92
93#define MSR_THERM_INTR_HITEMP __BIT(0) 93#define MSR_THERM_INTR_HITEMP __BIT(0)
94#define MSR_THERM_INTR_LOTEMPT __BIT(1) 94#define MSR_THERM_INTR_LOTEMPT __BIT(1)
95#define MSR_THERM_INTR_PROCHOT __BIT(2) 95#define MSR_THERM_INTR_PROCHOT __BIT(2)
96#define MSR_THERM_INTR_FORCPR __BIT(3) 96#define MSR_THERM_INTR_FORCPR __BIT(3)
97#define MSR_THERM_INTR_OVERHEAT __BIT(4) 97#define MSR_THERM_INTR_OVERHEAT __BIT(4)
98#define MSR_THERM_INTR_TRIP1_VAL __BITS(8, 14) 98#define MSR_THERM_INTR_TRIP1_VAL __BITS(8, 14)
99#define MSR_THERM_INTR_TRIP1 __BIT(15) 99#define MSR_THERM_INTR_TRIP1 __BIT(15)
100#define MSR_THERM_INTR_TRIP2_VAL __BITS(16, 22) 100#define MSR_THERM_INTR_TRIP2_VAL __BITS(16, 22)
101#define MSR_THERM_INTR_TRIP2 __BIT(23) 101#define MSR_THERM_INTR_TRIP2 __BIT(23)
102 102
103#define MSR_TEMP_TARGET_READOUT __BITS(16, 23) 103#define MSR_TEMP_TARGET_READOUT __BITS(16, 23)
104 104
 105#define TJMAX_DEFAULT 100
 106#define TJMAX_LIMIT_LOW 60
 107#define TJMAX_LIMIT_HIGH 120
 108
105static int coretemp_match(device_t, cfdata_t, void *); 109static int coretemp_match(device_t, cfdata_t, void *);
106static void coretemp_attach(device_t, device_t, void *); 110static void coretemp_attach(device_t, device_t, void *);
107static int coretemp_detach(device_t, int); 111static int coretemp_detach(device_t, int);
108static int coretemp_quirks(struct cpu_info *); 112static int coretemp_quirks(struct cpu_info *);
109static void coretemp_tjmax(device_t); 113static void coretemp_tjmax(device_t);
110static void coretemp_refresh(struct sysmon_envsys *, envsys_data_t *); 114static void coretemp_refresh(struct sysmon_envsys *, envsys_data_t *);
111static void coretemp_refresh_xcall(void *, void *); 115static void coretemp_refresh_xcall(void *, void *);
112 116
113struct coretemp_softc { 117struct coretemp_softc {
114 device_t sc_dev; 118 device_t sc_dev;
115 struct cpu_info *sc_ci; 119 struct cpu_info *sc_ci;
116 struct sysmon_envsys *sc_sme; 120 struct sysmon_envsys *sc_sme;
117 envsys_data_t sc_sensor; 121 envsys_data_t sc_sensor;
@@ -249,36 +253,35 @@ coretemp_quirks(struct cpu_info *ci) @@ -249,36 +253,35 @@ coretemp_quirks(struct cpu_info *ci)
249 253
250 if (msr < 0x39) 254 if (msr < 0x39)
251 return 0; 255 return 0;
252 } 256 }
253 257
254 return 1; 258 return 1;
255} 259}
256 260
257void 261void
258coretemp_tjmax(device_t self) 262coretemp_tjmax(device_t self)
259{ 263{
260 struct coretemp_softc *sc = device_private(self); 264 struct coretemp_softc *sc = device_private(self);
261 struct cpu_info *ci = sc->sc_ci; 265 struct cpu_info *ci = sc->sc_ci;
262 uint32_t model, stepping; 
263 uint64_t msr; 266 uint64_t msr;
 267 uint32_t model, stepping;
 268 int tjmax;
264 269
265 model = CPUID_TO_MODEL(ci->ci_signature); 270 model = CPUID_TO_MODEL(ci->ci_signature);
266 stepping = CPUID_TO_STEPPING(ci->ci_signature); 271 stepping = CPUID_TO_STEPPING(ci->ci_signature);
267 272
268 /* 273 /* Set the initial value. */
269 * Use 100C as the initial value. 274 sc->sc_tjmax = TJMAX_DEFAULT;
270 */ 
271 sc->sc_tjmax = 100; 
272 275
273 if ((model == 0x0f && stepping >= 2) || (model == 0x0e)) { 276 if ((model == 0x0f && stepping >= 2) || (model == 0x0e)) {
274 /* 277 /*
275 * Check MSR_IA32_PLATFORM_ID(0x17) bit 28. It's not documented 278 * Check MSR_IA32_PLATFORM_ID(0x17) bit 28. It's not documented
276 * in the datasheet, but the following page describes the 279 * in the datasheet, but the following page describes the
277 * detail: 280 * detail:
278 * http://software.intel.com/en-us/articles/ 281 * http://software.intel.com/en-us/articles/
279 * mobile-intel-core2-processor-detection-table/ 282 * mobile-intel-core2-processor-detection-table/
280 * Was: http://softwarecommunity.intel.com/Wiki/Mobility/ 283 * Was: http://softwarecommunity.intel.com/Wiki/Mobility/
281 * 720.htm 284 * 720.htm
282 */ 285 */
283 if (rdmsr_safe(MSR_IA32_PLATFORM_ID, &msr) != 0) 286 if (rdmsr_safe(MSR_IA32_PLATFORM_ID, &msr) != 0)
284 goto notee; 287 goto notee;
@@ -294,57 +297,57 @@ coretemp_tjmax(device_t self) @@ -294,57 +297,57 @@ coretemp_tjmax(device_t self)
294 } 297 }
295 } else if (model == 0x17 && stepping == 0x06) { 298 } else if (model == 0x17 && stepping == 0x06) {
296 /* The mobile Penryn family. */ 299 /* The mobile Penryn family. */
297 sc->sc_tjmax = 105; 300 sc->sc_tjmax = 105;
298 return; 301 return;
299 } else if (model == 0x1c) { 302 } else if (model == 0x1c) {
300 if (stepping == 0x0a) { 303 if (stepping == 0x0a) {
301 /* 45nm Atom D400, N400 and D500 series */ 304 /* 45nm Atom D400, N400 and D500 series */
302 sc->sc_tjmax = 100; 305 sc->sc_tjmax = 100;
303 } else 306 } else
304 sc->sc_tjmax = 90; 307 sc->sc_tjmax = 90;
305 } else { 308 } else {
306notee: 309notee:
307 /* 310 /* Attempt to get Tj(max) from IA32_TEMPERATURE_TARGET. */
308 * Attempt to get Tj(max) from IA32_TEMPERATURE_TARGET, 311 if (rdmsr_safe(MSR_TEMPERATURE_TARGET, &msr) == EFAULT) {
309 * but only consider the interval [70, 110] C as valid. 312 aprint_error_dev(sc->sc_dev,
310 * It is not fully known which CPU models have the MSR. 313 "Failed to read TEMPERATURE_TARGET MSR. "
311 */ 314 "Use the default (%d)\n", sc->sc_tjmax);
312 if (rdmsr_safe(MSR_TEMPERATURE_TARGET, &msr) == EFAULT) 
313 return; 
314 
315 msr = __SHIFTOUT(msr, MSR_TEMP_TARGET_READOUT); 
316 
317 if (msr >= 70 && msr <= 110) { 
318 sc->sc_tjmax = msr; 
319 return; 315 return;
320 } 316 }
 317
 318 tjmax = __SHIFTOUT(msr, MSR_TEMP_TARGET_READOUT);
 319 if ((tjmax < TJMAX_LIMIT_LOW) || (tjmax > TJMAX_LIMIT_HIGH))
 320 aprint_error_dev(sc->sc_dev,
 321 "WARNING: Tjmax(%d) might exceeded the limit.\n",
 322 tjmax);
 323 sc->sc_tjmax = tjmax;
321 } 324 }
322} 325}
323 326
324static void 327static void
325coretemp_refresh(struct sysmon_envsys *sme, envsys_data_t *edata) 328coretemp_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
326{ 329{
327 struct coretemp_softc *sc = sme->sme_cookie; 330 struct coretemp_softc *sc = sme->sme_cookie;
328 uint64_t xc; 331 uint64_t xc;
329 332
330 xc = xc_unicast(0, coretemp_refresh_xcall, sc, edata, sc->sc_ci); 333 xc = xc_unicast(0, coretemp_refresh_xcall, sc, edata, sc->sc_ci);
331 xc_wait(xc); 334 xc_wait(xc);
332} 335}
333 336
334static void 337static void
335coretemp_refresh_xcall(void *arg0, void *arg1) 338coretemp_refresh_xcall(void *arg0, void *arg1)
336{ 339{
337 struct coretemp_softc *sc = arg0; 340 struct coretemp_softc *sc = arg0;
338 envsys_data_t *edata = arg1; 341 envsys_data_t *edata = arg1;
339 uint64_t msr; 342 uint64_t msr;
340 343
341 msr = rdmsr(MSR_THERM_STATUS); 344 msr = rdmsr(MSR_THERM_STATUS);
342 345
343 if ((msr & MSR_THERM_STATUS_VALID) == 0) 346 if ((msr & MSR_THERM_STATUS_VALID) == 0)
344 edata->state = ENVSYS_SINVALID; 347 edata->state = ENVSYS_SINVALID;
345 else { 348 else {
346 /* 349 /*
347 * The temperature is computed by 350 * The temperature is computed by
348 * subtracting the reading by Tj(max). 351 * subtracting the reading by Tj(max).
349 */ 352 */
350 edata->value_cur = sc->sc_tjmax; 353 edata->value_cur = sc->sc_tjmax;