Improved Winbond temperature reading. Temperatures create by adding PECI Agent values (delta to TCC Activation Temperature) to a (possibly uncalibrated) TBase are not read. Direct reading temperatures from sensor report register if available. Added lower bound for temperatures on Winbond chips. Nvidia GPUs are now displayed even if they do not have any sensors.
authormoel.mich
Sat, 20 Feb 2010 19:51:10 +0000
changeset 565cb7eb5bf628
parent 55 898935080fd6
child 57 142907c75be4
Improved Winbond temperature reading. Temperatures create by adding PECI Agent values (delta to TCC Activation Temperature) to a (possibly uncalibrated) TBase are not read. Direct reading temperatures from sensor report register if available. Added lower bound for temperatures on Winbond chips. Nvidia GPUs are now displayed even if they do not have any sensors.
Hardware/LPC/W836XX.cs
Hardware/Nvidia/NvidiaGPU.cs
Hardware/Nvidia/NvidiaGroup.cs
Properties/AssemblyInfo.cs
     1.1 --- a/Hardware/LPC/W836XX.cs	Fri Feb 19 19:50:07 2010 +0000
     1.2 +++ b/Hardware/LPC/W836XX.cs	Sat Feb 20 19:51:10 2010 +0000
     1.3 @@ -67,8 +67,13 @@
     1.4      private const byte VOLTAGE_BASE_REG = 0x20;
     1.5      private const byte BANK_SELECT_REGISTER = 0x4E;
     1.6      private const byte VENDOR_ID_REGISTER = 0x4F;
     1.7 -    private const byte TEMPERATURE_BASE_REG = 0x50;
     1.8 -    private const byte TEMPERATURE_SYS_REG = 0x27;    
     1.9 +    private const byte TEMPERATURE_SOURCE_SELECT_REG = 0x49;
    1.10 +
    1.11 +    private string[] TEMPERATURE_NAME = 
    1.12 +      new string[] {"CPU", "Auxiliary", "System"};
    1.13 +    private byte[] TEMPERATURE_REG = new byte[] { 0x50, 0x50, 0x27 };
    1.14 +    private byte[] TEMPERATURE_BANK = new byte[] { 1, 2, 0 };
    1.15 +    private byte[] TEMPERATURE_SEL = new byte[] { 1, 2, 0 };
    1.16  
    1.17      private byte[] FAN_TACHO_REG = new byte[] { 0x28, 0x29, 0x2A, 0x3F, 0x53 };
    1.18      private byte[] FAN_TACHO_BANK = new byte[] { 0, 0, 0, 0, 5 };       
    1.19 @@ -88,6 +93,17 @@
    1.20          (ushort)(address + DATA_REGISTER_OFFSET));
    1.21      } 
    1.22  
    1.23 +    private void WriteByte(byte bank, byte register, byte value) {
    1.24 +      WinRing0.WriteIoPortByte(
    1.25 +         (ushort)(address + ADDRESS_REGISTER_OFFSET), BANK_SELECT_REGISTER);
    1.26 +      WinRing0.WriteIoPortByte(
    1.27 +         (ushort)(address + DATA_REGISTER_OFFSET), bank);
    1.28 +      WinRing0.WriteIoPortByte(
    1.29 +         (ushort)(address + ADDRESS_REGISTER_OFFSET), register);
    1.30 +      WinRing0.WriteIoPortByte(
    1.31 +         (ushort)(address + DATA_REGISTER_OFFSET), value); 
    1.32 +    }
    1.33 +   
    1.34      public W836XX(Chip chip, byte revision, ushort address) 
    1.35        : base(chip)
    1.36      {
    1.37 @@ -96,10 +112,29 @@
    1.38  
    1.39        available = IsWinbondVendor();
    1.40  
    1.41 -      temperatures = new Sensor[3];
    1.42 -      temperatures[0] = new Sensor("CPU", 0, SensorType.Temperature, this);
    1.43 -      temperatures[1] = new Sensor("Auxiliary", 1, SensorType.Temperature, this);
    1.44 -      temperatures[2] = new Sensor("System", 2, SensorType.Temperature, this);
    1.45 +      List<Sensor> list = new List<Sensor>();
    1.46 +      switch (chip) {
    1.47 +        case Chip.W83627DHG:
    1.48 +          // do not add temperature sensor registers that read PECI agents
    1.49 +          byte sel = ReadByte(0, TEMPERATURE_SOURCE_SELECT_REG);
    1.50 +          if ((sel & 0x07) == 0)
    1.51 +            list.Add(new Sensor(TEMPERATURE_NAME[0], 0,
    1.52 +              SensorType.Temperature, this));
    1.53 +          if ((sel & 0x70) == 0)
    1.54 +            list.Add(new Sensor(TEMPERATURE_NAME[1], 1,
    1.55 +              SensorType.Temperature, this));
    1.56 +          list.Add(new Sensor(TEMPERATURE_NAME[2], 2,
    1.57 +            SensorType.Temperature, this));
    1.58 +          break;
    1.59 +        default:
    1.60 +          // no PECI support or extra sensor report register
    1.61 +          for (int i = 0; i < TEMPERATURE_NAME.Length; i++) {
    1.62 +            list.Add(new Sensor(TEMPERATURE_NAME[i], i,
    1.63 +              SensorType.Temperature, this));
    1.64 +          }
    1.65 +          break;
    1.66 +      }
    1.67 +      temperatures = list.ToArray();
    1.68  
    1.69        switch (chip) {
    1.70          case Chip.W83627DHG:
    1.71 @@ -145,6 +180,7 @@
    1.72      }
    1.73  
    1.74      public void Update() {
    1.75 +
    1.76        foreach (Sensor sensor in voltages) {
    1.77          if (sensor.Index < 7) {
    1.78            int value = ReadByte(0, (byte)(VOLTAGE_BASE_REG + sensor.Index));
    1.79 @@ -157,7 +193,7 @@
    1.80            // Battery voltage
    1.81            bool valid = (ReadByte(0, 0x5D) & 0x01) > 0;
    1.82            if (valid) {
    1.83 -            sensor.Value = 
    1.84 +            sensor.Value =
    1.85                0.008f * voltageGains[sensor.Index] * ReadByte(5, 0x51);
    1.86              ActivateSensor(sensor);
    1.87            } else
    1.88 @@ -167,18 +203,32 @@
    1.89  
    1.90        foreach (Sensor sensor in temperatures) {
    1.91          int value;
    1.92 -        if (sensor.Index < 2) {
    1.93 -          value = (sbyte)ReadByte((byte)(sensor.Index + 1), TEMPERATURE_BASE_REG);
    1.94 -          value = (value << 1) | ReadByte((byte)(sensor.Index + 1),
    1.95 -            (byte)(TEMPERATURE_BASE_REG + 1)) >> 7;
    1.96 +        switch (chip) {
    1.97 +          case Chip.W83667HG:
    1.98 +          case Chip.W83667HGB:
    1.99 +            WriteByte(0, 0x7D, TEMPERATURE_SEL[sensor.Index]);
   1.100 +            value = ((sbyte)ReadByte(0, 0x7E)) << 1;
   1.101 +            break;
   1.102 +          case Chip.W83627DHGP:
   1.103 +            WriteByte(0, 0x7C, TEMPERATURE_SEL[sensor.Index]);
   1.104 +            value = ((sbyte)ReadByte(0, 0x7D)) << 1;
   1.105 +            break;
   1.106 +          default:
   1.107 +            value = ((sbyte)ReadByte(TEMPERATURE_BANK[sensor.Index],
   1.108 +              TEMPERATURE_REG[sensor.Index])) << 1;
   1.109 +            if (TEMPERATURE_BANK[sensor.Index] > 0) {
   1.110 +              value |= ReadByte(TEMPERATURE_BANK[sensor.Index],
   1.111 +                (byte)(TEMPERATURE_REG[sensor.Index] + 1)) >> 7;
   1.112 +            }            
   1.113 +            break;
   1.114 +        }
   1.115 +        float temperature = value / 2.0f;
   1.116 +        if (temperature <= 125 && temperature >= -55) {
   1.117 +          sensor.Value = temperature;
   1.118 +          ActivateSensor(sensor);
   1.119          } else {
   1.120 -          value = (sbyte)ReadByte(0, TEMPERATURE_SYS_REG) << 1;
   1.121 +          DeactivateSensor(sensor);
   1.122          }
   1.123 -        sensor.Value = value / 2.0f;
   1.124 -        if (value < 0xFE)
   1.125 -          ActivateSensor(sensor);
   1.126 -        else
   1.127 -          DeactivateSensor(sensor);
   1.128        }
   1.129  
   1.130        long bits = 0;
   1.131 @@ -212,7 +262,7 @@
   1.132        r.AppendLine();
   1.133        r.AppendLine("      00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
   1.134        r.AppendLine();
   1.135 -      for (int i = 0; i < 0x7; i++) {
   1.136 +      for (int i = 0; i <= 0x7; i++) {
   1.137          r.Append(" "); r.Append((i << 4).ToString("X2")); r.Append("  ");
   1.138          for (int j = 0; j <= 0xF; j++) {
   1.139            r.Append(" ");
     2.1 --- a/Hardware/Nvidia/NvidiaGPU.cs	Fri Feb 19 19:50:07 2010 +0000
     2.2 +++ b/Hardware/Nvidia/NvidiaGPU.cs	Sat Feb 20 19:51:10 2010 +0000
     2.3 @@ -50,57 +50,45 @@
     2.4      private Sensor[] temperatures;
     2.5      private Sensor fan = null;
     2.6  
     2.7 -    private bool available;
     2.8 +    public NvidiaGPU(int adapterIndex, NvPhysicalGpuHandle handle) {
     2.9 +      string gpuName;
    2.10 +      if (NVAPI.NvAPI_GPU_GetFullName(handle, out gpuName) == NvStatus.OK) {
    2.11 +        this.name = "NVIDIA " + gpuName.Trim();
    2.12 +      } else {
    2.13 +        this.name = "NVIDIA";
    2.14 +      }
    2.15 +      this.icon = Utilities.EmbeddedResources.GetImage("nvidia.png");
    2.16 +      this.adapterIndex = adapterIndex;
    2.17 +      this.handle = handle;
    2.18  
    2.19 -    public NvidiaGPU(int adapterIndex, NvPhysicalGpuHandle handle) {
    2.20 -      try {
    2.21 -        string gpuName;
    2.22 -        if (NVAPI.NvAPI_GPU_GetFullName(handle, out gpuName) == NvStatus.OK) {
    2.23 -          this.name = "NVIDIA " + gpuName.Trim();
    2.24 -        } else {
    2.25 -          this.name = "NVIDIA";
    2.26 +      NvGPUThermalSettings settings = GetThermalSettings();
    2.27 +      temperatures = new Sensor[settings.Count];
    2.28 +      for (int i = 0; i < temperatures.Length; i++) {
    2.29 +        NvSensor sensor = settings.Sensor[i];
    2.30 +        string name;
    2.31 +        switch (sensor.Target) {
    2.32 +          case NvThermalTarget.BOARD: name = "GPU Board"; break;
    2.33 +          case NvThermalTarget.GPU: name = "GPU Core"; break;
    2.34 +          case NvThermalTarget.MEMORY: name = "GPU Memory"; break;
    2.35 +          case NvThermalTarget.POWER_SUPPLY: name = "GPU Power Supply"; break;
    2.36 +          case NvThermalTarget.UNKNOWN: name = "GPU Unknown"; break;
    2.37 +          default: name = "GPU"; break;
    2.38          }
    2.39 -        this.icon = Utilities.EmbeddedResources.GetImage("nvidia.png");
    2.40 -        this.adapterIndex = adapterIndex;
    2.41 -        this.handle = handle;
    2.42 +        temperatures[i] = new Sensor(name, i, sensor.DefaultMaxTemp,
    2.43 +          SensorType.Temperature, this);
    2.44 +        ActivateSensor(temperatures[i]);
    2.45 +      }
    2.46  
    2.47 -        NvGPUThermalSettings settings = GetThermalSettings();
    2.48 -        temperatures = new Sensor[settings.Count];
    2.49 -        for (int i = 0; i < temperatures.Length; i++) {
    2.50 -          NvSensor sensor = settings.Sensor[i];
    2.51 -          string name;
    2.52 -          switch (sensor.Target) {
    2.53 -            case NvThermalTarget.BOARD: name = "GPU Board"; break;
    2.54 -            case NvThermalTarget.GPU: name = "GPU Core"; break;
    2.55 -            case NvThermalTarget.MEMORY: name = "GPU Memory"; break;
    2.56 -            case NvThermalTarget.POWER_SUPPLY: name = "GPU Power Supply"; break;
    2.57 -            case NvThermalTarget.UNKNOWN: name = "GPU Unknown"; break;
    2.58 -            default: name = "GPU"; break;
    2.59 -          }
    2.60 -          temperatures[i] = new Sensor(name, i, sensor.DefaultMaxTemp, 
    2.61 -            SensorType.Temperature, this);
    2.62 -          ActivateSensor(temperatures[i]);
    2.63 +      int value;
    2.64 +      if (NVAPI.NvAPI_GPU_GetTachReading != null &&
    2.65 +        NVAPI.NvAPI_GPU_GetTachReading(handle, out value) == NvStatus.OK) {
    2.66 +        if (value > 0) {
    2.67 +          fan = new Sensor("GPU", 0, SensorType.Fan, this);
    2.68 +          ActivateSensor(fan);
    2.69          }
    2.70 -        
    2.71 -        int value;
    2.72 -        if (NVAPI.NvAPI_GPU_GetTachReading != null &&
    2.73 -          NVAPI.NvAPI_GPU_GetTachReading(handle, out value) == NvStatus.OK) {
    2.74 -          if (value > 0) {
    2.75 -            fan = new Sensor("GPU", 0, SensorType.Fan, this);
    2.76 -            ActivateSensor(fan);
    2.77 -          }
    2.78 -        }
    2.79 -
    2.80 -        available = temperatures.Length > 0 || fan != null;
    2.81 -      } catch (Exception e) {
    2.82 -        System.Windows.Forms.MessageBox.Show(e.Message + "\n" + e.StackTrace);
    2.83        }
    2.84      }
    2.85  
    2.86 -    public bool IsAvailable {
    2.87 -      get { return available; }
    2.88 -    }
    2.89 -
    2.90      public string Name {
    2.91        get { return name; }
    2.92      }
     3.1 --- a/Hardware/Nvidia/NvidiaGroup.cs	Fri Feb 19 19:50:07 2010 +0000
     3.2 +++ b/Hardware/Nvidia/NvidiaGroup.cs	Sat Feb 20 19:51:10 2010 +0000
     3.3 @@ -64,11 +64,8 @@
     3.4        report.AppendLine(count.ToString());
     3.5        report.AppendLine();
     3.6  
     3.7 -      for (int i = 0; i < count; i++) {
     3.8 -        NvidiaGPU gpu = new NvidiaGPU(i, handles[i]);
     3.9 -        if (gpu.IsAvailable)
    3.10 -          hardware.Add(gpu);
    3.11 -      }
    3.12 +      for (int i = 0; i < count; i++) 
    3.13 +        hardware.Add(new NvidiaGPU(i, handles[i]));
    3.14      }
    3.15  
    3.16      public IHardware[] Hardware {
     4.1 --- a/Properties/AssemblyInfo.cs	Fri Feb 19 19:50:07 2010 +0000
     4.2 +++ b/Properties/AssemblyInfo.cs	Sat Feb 20 19:51:10 2010 +0000
     4.3 @@ -69,5 +69,5 @@
     4.4  // You can specify all the values or you can default the Build and Revision Numbers 
     4.5  // by using the '*' as shown below:
     4.6  // [assembly: AssemblyVersion("1.0.*")]
     4.7 -[assembly: AssemblyVersion("0.1.22.0")]
     4.8 -[assembly: AssemblyFileVersion("0.1.22.0")]
     4.9 +[assembly: AssemblyVersion("0.1.22.1")]
    4.10 +[assembly: AssemblyFileVersion("0.1.22.1")]