From bcb19ae527ad5b7e7c3688f7a8e0409fd2994059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=B6ller?= Date: Sat, 20 Feb 2010 19:51:10 +0000 Subject: [PATCH] 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 | 84 +++++++++++++++++++++++++++------- Hardware/Nvidia/NvidiaGPU.cs | 80 ++++++++++++++------------------ Hardware/Nvidia/NvidiaGroup.cs | 7 +-- Properties/AssemblyInfo.cs | 4 +- 4 files changed, 105 insertions(+), 70 deletions(-) diff --git a/Hardware/LPC/W836XX.cs b/Hardware/LPC/W836XX.cs index 1f8be64..fb1abd7 100644 --- a/Hardware/LPC/W836XX.cs +++ b/Hardware/LPC/W836XX.cs @@ -67,8 +67,13 @@ namespace OpenHardwareMonitor.Hardware.LPC { private const byte VOLTAGE_BASE_REG = 0x20; private const byte BANK_SELECT_REGISTER = 0x4E; private const byte VENDOR_ID_REGISTER = 0x4F; - private const byte TEMPERATURE_BASE_REG = 0x50; - private const byte TEMPERATURE_SYS_REG = 0x27; + private const byte TEMPERATURE_SOURCE_SELECT_REG = 0x49; + + private string[] TEMPERATURE_NAME = + new string[] {"CPU", "Auxiliary", "System"}; + private byte[] TEMPERATURE_REG = new byte[] { 0x50, 0x50, 0x27 }; + private byte[] TEMPERATURE_BANK = new byte[] { 1, 2, 0 }; + private byte[] TEMPERATURE_SEL = new byte[] { 1, 2, 0 }; private byte[] FAN_TACHO_REG = new byte[] { 0x28, 0x29, 0x2A, 0x3F, 0x53 }; private byte[] FAN_TACHO_BANK = new byte[] { 0, 0, 0, 0, 5 }; @@ -88,6 +93,17 @@ namespace OpenHardwareMonitor.Hardware.LPC { (ushort)(address + DATA_REGISTER_OFFSET)); } + private void WriteByte(byte bank, byte register, byte value) { + WinRing0.WriteIoPortByte( + (ushort)(address + ADDRESS_REGISTER_OFFSET), BANK_SELECT_REGISTER); + WinRing0.WriteIoPortByte( + (ushort)(address + DATA_REGISTER_OFFSET), bank); + WinRing0.WriteIoPortByte( + (ushort)(address + ADDRESS_REGISTER_OFFSET), register); + WinRing0.WriteIoPortByte( + (ushort)(address + DATA_REGISTER_OFFSET), value); + } + public W836XX(Chip chip, byte revision, ushort address) : base(chip) { @@ -96,10 +112,29 @@ namespace OpenHardwareMonitor.Hardware.LPC { available = IsWinbondVendor(); - temperatures = new Sensor[3]; - temperatures[0] = new Sensor("CPU", 0, SensorType.Temperature, this); - temperatures[1] = new Sensor("Auxiliary", 1, SensorType.Temperature, this); - temperatures[2] = new Sensor("System", 2, SensorType.Temperature, this); + List list = new List(); + switch (chip) { + case Chip.W83627DHG: + // do not add temperature sensor registers that read PECI agents + byte sel = ReadByte(0, TEMPERATURE_SOURCE_SELECT_REG); + if ((sel & 0x07) == 0) + list.Add(new Sensor(TEMPERATURE_NAME[0], 0, + SensorType.Temperature, this)); + if ((sel & 0x70) == 0) + list.Add(new Sensor(TEMPERATURE_NAME[1], 1, + SensorType.Temperature, this)); + list.Add(new Sensor(TEMPERATURE_NAME[2], 2, + SensorType.Temperature, this)); + break; + default: + // no PECI support or extra sensor report register + for (int i = 0; i < TEMPERATURE_NAME.Length; i++) { + list.Add(new Sensor(TEMPERATURE_NAME[i], i, + SensorType.Temperature, this)); + } + break; + } + temperatures = list.ToArray(); switch (chip) { case Chip.W83627DHG: @@ -145,6 +180,7 @@ namespace OpenHardwareMonitor.Hardware.LPC { } public void Update() { + foreach (Sensor sensor in voltages) { if (sensor.Index < 7) { int value = ReadByte(0, (byte)(VOLTAGE_BASE_REG + sensor.Index)); @@ -157,7 +193,7 @@ namespace OpenHardwareMonitor.Hardware.LPC { // Battery voltage bool valid = (ReadByte(0, 0x5D) & 0x01) > 0; if (valid) { - sensor.Value = + sensor.Value = 0.008f * voltageGains[sensor.Index] * ReadByte(5, 0x51); ActivateSensor(sensor); } else @@ -167,18 +203,32 @@ namespace OpenHardwareMonitor.Hardware.LPC { foreach (Sensor sensor in temperatures) { int value; - if (sensor.Index < 2) { - value = (sbyte)ReadByte((byte)(sensor.Index + 1), TEMPERATURE_BASE_REG); - value = (value << 1) | ReadByte((byte)(sensor.Index + 1), - (byte)(TEMPERATURE_BASE_REG + 1)) >> 7; - } else { - value = (sbyte)ReadByte(0, TEMPERATURE_SYS_REG) << 1; + switch (chip) { + case Chip.W83667HG: + case Chip.W83667HGB: + WriteByte(0, 0x7D, TEMPERATURE_SEL[sensor.Index]); + value = ((sbyte)ReadByte(0, 0x7E)) << 1; + break; + case Chip.W83627DHGP: + WriteByte(0, 0x7C, TEMPERATURE_SEL[sensor.Index]); + value = ((sbyte)ReadByte(0, 0x7D)) << 1; + break; + default: + value = ((sbyte)ReadByte(TEMPERATURE_BANK[sensor.Index], + TEMPERATURE_REG[sensor.Index])) << 1; + if (TEMPERATURE_BANK[sensor.Index] > 0) { + value |= ReadByte(TEMPERATURE_BANK[sensor.Index], + (byte)(TEMPERATURE_REG[sensor.Index] + 1)) >> 7; + } + break; } - sensor.Value = value / 2.0f; - if (value < 0xFE) + float temperature = value / 2.0f; + if (temperature <= 125 && temperature >= -55) { + sensor.Value = temperature; ActivateSensor(sensor); - else + } else { DeactivateSensor(sensor); + } } long bits = 0; @@ -212,7 +262,7 @@ namespace OpenHardwareMonitor.Hardware.LPC { r.AppendLine(); r.AppendLine(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F"); r.AppendLine(); - for (int i = 0; i < 0x7; i++) { + for (int i = 0; i <= 0x7; i++) { r.Append(" "); r.Append((i << 4).ToString("X2")); r.Append(" "); for (int j = 0; j <= 0xF; j++) { r.Append(" "); diff --git a/Hardware/Nvidia/NvidiaGPU.cs b/Hardware/Nvidia/NvidiaGPU.cs index 3b1c090..cf49f14 100644 --- a/Hardware/Nvidia/NvidiaGPU.cs +++ b/Hardware/Nvidia/NvidiaGPU.cs @@ -50,55 +50,43 @@ namespace OpenHardwareMonitor.Hardware.Nvidia { private Sensor[] temperatures; private Sensor fan = null; - private bool available; - public NvidiaGPU(int adapterIndex, NvPhysicalGpuHandle handle) { - try { - string gpuName; - if (NVAPI.NvAPI_GPU_GetFullName(handle, out gpuName) == NvStatus.OK) { - this.name = "NVIDIA " + gpuName.Trim(); - } else { - this.name = "NVIDIA"; - } - this.icon = Utilities.EmbeddedResources.GetImage("nvidia.png"); - this.adapterIndex = adapterIndex; - this.handle = handle; - - NvGPUThermalSettings settings = GetThermalSettings(); - temperatures = new Sensor[settings.Count]; - for (int i = 0; i < temperatures.Length; i++) { - NvSensor sensor = settings.Sensor[i]; - string name; - switch (sensor.Target) { - case NvThermalTarget.BOARD: name = "GPU Board"; break; - case NvThermalTarget.GPU: name = "GPU Core"; break; - case NvThermalTarget.MEMORY: name = "GPU Memory"; break; - case NvThermalTarget.POWER_SUPPLY: name = "GPU Power Supply"; break; - case NvThermalTarget.UNKNOWN: name = "GPU Unknown"; break; - default: name = "GPU"; break; - } - temperatures[i] = new Sensor(name, i, sensor.DefaultMaxTemp, - SensorType.Temperature, this); - ActivateSensor(temperatures[i]); - } - - int value; - if (NVAPI.NvAPI_GPU_GetTachReading != null && - NVAPI.NvAPI_GPU_GetTachReading(handle, out value) == NvStatus.OK) { - if (value > 0) { - fan = new Sensor("GPU", 0, SensorType.Fan, this); - ActivateSensor(fan); - } - } - - available = temperatures.Length > 0 || fan != null; - } catch (Exception e) { - System.Windows.Forms.MessageBox.Show(e.Message + "\n" + e.StackTrace); + string gpuName; + if (NVAPI.NvAPI_GPU_GetFullName(handle, out gpuName) == NvStatus.OK) { + this.name = "NVIDIA " + gpuName.Trim(); + } else { + this.name = "NVIDIA"; } - } + this.icon = Utilities.EmbeddedResources.GetImage("nvidia.png"); + this.adapterIndex = adapterIndex; + this.handle = handle; - public bool IsAvailable { - get { return available; } + NvGPUThermalSettings settings = GetThermalSettings(); + temperatures = new Sensor[settings.Count]; + for (int i = 0; i < temperatures.Length; i++) { + NvSensor sensor = settings.Sensor[i]; + string name; + switch (sensor.Target) { + case NvThermalTarget.BOARD: name = "GPU Board"; break; + case NvThermalTarget.GPU: name = "GPU Core"; break; + case NvThermalTarget.MEMORY: name = "GPU Memory"; break; + case NvThermalTarget.POWER_SUPPLY: name = "GPU Power Supply"; break; + case NvThermalTarget.UNKNOWN: name = "GPU Unknown"; break; + default: name = "GPU"; break; + } + temperatures[i] = new Sensor(name, i, sensor.DefaultMaxTemp, + SensorType.Temperature, this); + ActivateSensor(temperatures[i]); + } + + int value; + if (NVAPI.NvAPI_GPU_GetTachReading != null && + NVAPI.NvAPI_GPU_GetTachReading(handle, out value) == NvStatus.OK) { + if (value > 0) { + fan = new Sensor("GPU", 0, SensorType.Fan, this); + ActivateSensor(fan); + } + } } public string Name { diff --git a/Hardware/Nvidia/NvidiaGroup.cs b/Hardware/Nvidia/NvidiaGroup.cs index eed24a9..60354f7 100644 --- a/Hardware/Nvidia/NvidiaGroup.cs +++ b/Hardware/Nvidia/NvidiaGroup.cs @@ -64,11 +64,8 @@ namespace OpenHardwareMonitor.Hardware.Nvidia { report.AppendLine(count.ToString()); report.AppendLine(); - for (int i = 0; i < count; i++) { - NvidiaGPU gpu = new NvidiaGPU(i, handles[i]); - if (gpu.IsAvailable) - hardware.Add(gpu); - } + for (int i = 0; i < count; i++) + hardware.Add(new NvidiaGPU(i, handles[i])); } public IHardware[] Hardware { diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index c8f85a7..99d5220 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -69,5 +69,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.1.22.0")] -[assembly: AssemblyFileVersion("0.1.22.0")] +[assembly: AssemblyVersion("0.1.22.1")] +[assembly: AssemblyFileVersion("0.1.22.1")]