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
This commit is contained in:
parent
007376c918
commit
7cbaa3e8e6
@ -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
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user