Added support for package level temperature sensors on new Intel Sandy Bridge CPUs.
1.1 --- a/Hardware/CPU/IntelCPU.cs Sun Jun 26 16:00:20 2011 +0000
1.2 +++ b/Hardware/CPU/IntelCPU.cs Sun Jun 26 17:00:32 2011 +0000
1.3 @@ -52,6 +52,7 @@
1.4 }
1.5
1.6 private readonly Sensor[] coreTemperatures;
1.7 + private readonly Sensor packageTemperature;
1.8 private readonly Sensor[] coreClocks;
1.9 private readonly Sensor busClock;
1.10
1.11 @@ -62,6 +63,7 @@
1.12 private const uint IA32_TEMPERATURE_TARGET = 0x01A2;
1.13 private const uint IA32_PERF_STATUS = 0x0198;
1.14 private const uint MSR_PLATFORM_INFO = 0xCE;
1.15 + private const uint IA32_PACKAGE_THERM_STATUS = 0x1B1;
1.16
1.17 private float[] Floats(float f) {
1.18 float[] result = new float[coreCount];
1.19 @@ -196,15 +198,16 @@
1.20 } break;
1.21 }
1.22
1.23 - // check if processor supports a digital thermal sensor
1.24 + // check if processor supports a digital thermal sensor at core level
1.25 if (cpuid[0][0].Data.GetLength(0) > 6 &&
1.26 - (cpuid[0][0].Data[6, 0] & 1) != 0) {
1.27 + (cpuid[0][0].Data[6, 0] & 1) != 0)
1.28 + {
1.29 coreTemperatures = new Sensor[coreCount];
1.30 for (int i = 0; i < coreTemperatures.Length; i++) {
1.31 coreTemperatures[i] = new Sensor(CoreString(i), i,
1.32 SensorType.Temperature, this, new [] {
1.33 new ParameterDescription(
1.34 - "TjMax [°C]", "TjMax temperature of the core.\n" +
1.35 + "TjMax [°C]", "TjMax temperature of the core sensor.\n" +
1.36 "Temperature = TjMax - TSlope * Value.", tjMax[i]),
1.37 new ParameterDescription("TSlope [°C]",
1.38 "Temperature slope of the digital thermal sensor.\n" +
1.39 @@ -215,6 +218,21 @@
1.40 coreTemperatures = new Sensor[0];
1.41 }
1.42
1.43 + // check if processor supports a digital thermal sensor at package level
1.44 + if (cpuid[0][0].Data.GetLength(0) > 6 &&
1.45 + (cpuid[0][0].Data[6, 0] & 0x40) != 0)
1.46 + {
1.47 + packageTemperature = new Sensor("CPU Package",
1.48 + coreTemperatures.Length, SensorType.Temperature, this, new[] {
1.49 + new ParameterDescription(
1.50 + "TjMax [°C]", "TjMax temperature of the package sensor.\n" +
1.51 + "Temperature = TjMax - TSlope * Value.", tjMax[0]),
1.52 + new ParameterDescription("TSlope [°C]",
1.53 + "Temperature slope of the digital thermal sensor.\n" +
1.54 + "Temperature = TjMax - TSlope * Value.", 1)}, settings);
1.55 + ActivateSensor(packageTemperature);
1.56 + }
1.57 +
1.58 busClock = new Sensor("Bus Speed", 0, SensorType.Clock, this, settings);
1.59 coreClocks = new Sensor[coreCount];
1.60 for (int i = 0; i < coreClocks.Length; i++) {
1.61 @@ -232,7 +250,8 @@
1.62 MSR_PLATFORM_INFO,
1.63 IA32_PERF_STATUS ,
1.64 IA32_THERM_STATUS_MSR,
1.65 - IA32_TEMPERATURE_TARGET
1.66 + IA32_TEMPERATURE_TARGET,
1.67 + IA32_PACKAGE_THERM_STATUS
1.68 };
1.69 }
1.70
1.71 @@ -271,6 +290,21 @@
1.72 }
1.73 }
1.74
1.75 + if (packageTemperature != null) {
1.76 + uint eax, edx;
1.77 + if (Ring0.RdmsrTx(
1.78 + IA32_THERM_STATUS_MSR, out eax, out edx,
1.79 + 1UL << cpuid[0][0].Thread)) {
1.80 + // get the dist from tjMax from bits 22:16
1.81 + float deltaT = ((eax & 0x007F0000) >> 16);
1.82 + float tjMax = packageTemperature.Parameters[0].Value;
1.83 + float tSlope = packageTemperature.Parameters[1].Value;
1.84 + packageTemperature.Value = tjMax - tSlope * deltaT;
1.85 + } else {
1.86 + packageTemperature.Value = null;
1.87 + }
1.88 + }
1.89 +
1.90 if (HasTimeStampCounter) {
1.91 double newBusClock = 0;
1.92 uint eax, edx;