Added support for package level temperature sensors on new Intel Sandy Bridge CPUs.
authormoel.mich
Sun, 26 Jun 2011 17:00:32 +0000
changeset 306e9127c00ada1
parent 305 9652074e6ee5
child 307 31b2b9b5eae9
Added support for package level temperature sensors on new Intel Sandy Bridge CPUs.
Hardware/CPU/IntelCPU.cs
     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;