coretemp.c (196889) | coretemp.c (210624) |
---|---|
1/*- 2 * Copyright (c) 2007, 2008 Rui Paulo <rpaulo@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 16 unchanged lines hidden (view full) --- 25 */ 26 27/* 28 * Device driver for Intel's On Die thermal sensor via MSR. 29 * First introduced in Intel's Core line of processors. 30 */ 31 32#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2007, 2008 Rui Paulo <rpaulo@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 16 unchanged lines hidden (view full) --- 25 */ 26 27/* 28 * Device driver for Intel's On Die thermal sensor via MSR. 29 * First introduced in Intel's Core line of processors. 30 */ 31 32#include <sys/cdefs.h> |
33__FBSDID("$FreeBSD: head/sys/dev/coretemp/coretemp.c 196889 2009-09-06 12:01:29Z nork $"); | 33__FBSDID("$FreeBSD: head/sys/dev/coretemp/coretemp.c 210624 2010-07-29 19:08:22Z delphij $"); |
34 35#include <sys/param.h> 36#include <sys/bus.h> 37#include <sys/systm.h> 38#include <sys/types.h> 39#include <sys/module.h> 40#include <sys/conf.h> 41#include <sys/kernel.h> --- 86 unchanged lines hidden (view full) --- 128} 129 130static int 131coretemp_attach(device_t dev) 132{ 133 struct coretemp_softc *sc = device_get_softc(dev); 134 device_t pdev; 135 uint64_t msr; | 34 35#include <sys/param.h> 36#include <sys/bus.h> 37#include <sys/systm.h> 38#include <sys/types.h> 39#include <sys/module.h> 40#include <sys/conf.h> 41#include <sys/kernel.h> --- 86 unchanged lines hidden (view full) --- 128} 129 130static int 131coretemp_attach(device_t dev) 132{ 133 struct coretemp_softc *sc = device_get_softc(dev); 134 device_t pdev; 135 uint64_t msr; |
136 int cpu_model; 137 int cpu_mask; | 136 int cpu_model, cpu_stepping; 137 int ret, tjtarget; |
138 139 sc->sc_dev = dev; 140 pdev = device_get_parent(dev); | 138 139 sc->sc_dev = dev; 140 pdev = device_get_parent(dev); |
141 cpu_model = (cpu_id >> 4) & 15; 142 /* extended model */ 143 cpu_model += ((cpu_id >> 16) & 0xf) << 4; 144 cpu_mask = cpu_id & 15; | 141 cpu_model = CPUID_TO_MODEL(cpu_id); 142 cpu_stepping = cpu_id & CPUID_STEPPING; |
145 146 /* 147 * Some CPUs, namely the PIII, don't have thermal sensors, but 148 * report them when the CPUID check is performed in 149 * coretemp_identify(). This leads to a later GPF when the sensor 150 * is queried via a MSR, so we stop here. 151 */ 152 if (cpu_model < 0xe) --- 6 unchanged lines hidden (view full) --- 159 160 /* 161 * Check for errata AE18. 162 * "Processor Digital Thermal Sensor (DTS) Readout stops 163 * updating upon returning from C3/C4 state." 164 * 165 * Adapted from the Linux coretemp driver. 166 */ | 143 144 /* 145 * Some CPUs, namely the PIII, don't have thermal sensors, but 146 * report them when the CPUID check is performed in 147 * coretemp_identify(). This leads to a later GPF when the sensor 148 * is queried via a MSR, so we stop here. 149 */ 150 if (cpu_model < 0xe) --- 6 unchanged lines hidden (view full) --- 157 158 /* 159 * Check for errata AE18. 160 * "Processor Digital Thermal Sensor (DTS) Readout stops 161 * updating upon returning from C3/C4 state." 162 * 163 * Adapted from the Linux coretemp driver. 164 */ |
167 if (cpu_model == 0xe && cpu_mask < 0xc) { | 165 if (cpu_model == 0xe && cpu_stepping < 0xc) { |
168 msr = rdmsr(MSR_BIOS_SIGN); 169 msr = msr >> 32; 170 if (msr < 0x39) { 171 device_printf(dev, "not supported (Intel errata " 172 "AE18), try updating your BIOS\n"); 173 return (ENXIO); 174 } 175 } 176#endif | 166 msr = rdmsr(MSR_BIOS_SIGN); 167 msr = msr >> 32; 168 if (msr < 0x39) { 169 device_printf(dev, "not supported (Intel errata " 170 "AE18), try updating your BIOS\n"); 171 return (ENXIO); 172 } 173 } 174#endif |
175 |
|
177 /* | 176 /* |
178 * On some Core 2 CPUs, there's an undocumented MSR that 179 * can tell us if Tj(max) is 100 or 85. 180 * 181 * The if-clause for CPUs having the MSR_IA32_EXT_CONFIG was adapted 182 * from the Linux coretemp driver. | 177 * Use 100C as the initial value. |
183 */ 184 sc->sc_tjmax = 100; | 178 */ 179 sc->sc_tjmax = 100; |
185 if ((cpu_model == 0xf && cpu_mask >= 2) || cpu_model == 0xe) { | 180 181 /* 182 * Attempt to get Tj(max) from MSR IA32_TEMPERATURE_TARGET. 183 * 184 * This method is described in Intel white paper 185 * "CPU Monitoring With DTS/PECI". (#322683) 186 */ 187 ret = rdmsr_safe(MSR_IA32_TEMPERATURE_TARGET, &msr); 188 if (ret == 0) { 189 tjtarget = (msr >> 16) & 0xff; 190 /* 191 * On earlier generation of processors, the value obtained 192 * from IA32_TEMPERATURE_TARGET register is an offset that 193 * needs to be summed with a model specific base. It is 194 * however not clear what these numbers are, with the 195 * publicly available documents from Intel. 196 * 197 * For now, we consider [70, 100]C range, as described in 198 * #322683, as "reasonable" and accept these values 199 * whenever the MSR is available for read, regardless the 200 * CPU model. 201 */ 202 if (tjtarget >= 70 && tjtarget <= 100) 203 sc->sc_tjmax = tjtarget; 204 else 205 device_printf(dev, "Tj(target) value %d does " 206 "not seem right.\n", tjtarget); 207 } 208 209 if ((cpu_model == 0xf && cpu_stepping >= 2) || cpu_model == 0xe) { 210 /* 211 * On some Core 2 CPUs, there's an undocumented MSR that 212 * can tell us if Tj(max) is 100 or 85. 213 * 214 * The if-clause for CPUs having the MSR_IA32_EXT_CONFIG was adapted 215 * from the Linux coretemp driver. 216 */ |
186 msr = rdmsr(MSR_IA32_EXT_CONFIG); 187 if (msr & (1 << 30)) 188 sc->sc_tjmax = 85; 189 } 190 | 217 msr = rdmsr(MSR_IA32_EXT_CONFIG); 218 if (msr & (1 << 30)) 219 sc->sc_tjmax = 85; 220 } 221 |
222 if (bootverbose) 223 device_printf(dev, "Setting TjMax=%d\n", sc->sc_tjmax); 224 |
|
191 /* 192 * Add the "temperature" MIB to dev.cpu.N. 193 */ 194 sc->sc_oid = SYSCTL_ADD_PROC(device_get_sysctl_ctx(pdev), 195 SYSCTL_CHILDREN(device_get_sysctl_tree(pdev)), 196 OID_AUTO, "temperature", 197 CTLTYPE_INT | CTLFLAG_RD, 198 dev, 0, coretemp_get_temp_sysctl, "IK", --- 93 unchanged lines hidden --- | 225 /* 226 * Add the "temperature" MIB to dev.cpu.N. 227 */ 228 sc->sc_oid = SYSCTL_ADD_PROC(device_get_sysctl_ctx(pdev), 229 SYSCTL_CHILDREN(device_get_sysctl_tree(pdev)), 230 OID_AUTO, "temperature", 231 CTLTYPE_INT | CTLFLAG_RD, 232 dev, 0, coretemp_get_temp_sysctl, "IK", --- 93 unchanged lines hidden --- |