Add Zen 2 CCD temperatures and merged Tdie/Tctl.

Based on the work of @LeagueRaINi

Co-Authored-By: RaINi_ <razor13372k@gmail.com>
This commit is contained in:
Phyxion
2020-01-17 12:10:15 +01:00
co-authored by RaINi_
parent f51f0378ec
commit f7278652b5
2 changed files with 142 additions and 39 deletions
+118 -23
View File
@@ -93,10 +93,14 @@ namespace LibreHardwareMonitor.Hardware.CPU
{
private readonly Sensor _coreTemperatureTctl;
private readonly Sensor _coreTemperatureTdie;
private readonly Sensor _coreTemperatureTctlTdie;
private readonly Sensor[] _ccdTemperatures;
private readonly Sensor _coreVoltage;
private readonly Amd17Cpu _hw;
private readonly Sensor _packagePower;
private readonly Sensor _socVoltage;
private Sensor _ccdsMaxTemperature;
private Sensor _ccdsAverageTemperature;
private DateTime _lastPwrTime = new DateTime(0);
private uint _lastPwrValue;
@@ -108,20 +112,19 @@ namespace LibreHardwareMonitor.Hardware.CPU
_packagePower = new Sensor("Package Power", _hw._sensorPower++, SensorType.Power, _hw, _hw._settings);
_coreTemperatureTctl = new Sensor("Core (Tctl)", _hw._sensorTemperatures++, SensorType.Temperature, _hw, _hw._settings);
_coreTemperatureTdie = new Sensor("Core (Tdie)", _hw._sensorTemperatures++, SensorType.Temperature, _hw, _hw._settings);
_coreTemperatureTctlTdie = new Sensor("Core (Tctl/Tdie)", _hw._sensorTemperatures++, SensorType.Temperature, _hw, _hw._settings);
_ccdTemperatures = new Sensor[8]; // Hardcoded until there's a way to get max CCDs.
_coreVoltage = new Sensor("Core (SVI2 TFN)", _hw._sensorVoltage++, SensorType.Voltage, _hw, _hw._settings);
_socVoltage = new Sensor("SoC (SVI2 TFN)", _hw._sensorVoltage++, SensorType.Voltage, _hw, _hw._settings);
_hw.ActivateSensor(_packagePower);
_hw.ActivateSensor(_coreTemperatureTctl);
_hw.ActivateSensor(_coreTemperatureTdie);
_hw.ActivateSensor(_coreVoltage);
}
public List<NumaNode> Nodes { get; }
public void UpdateSensors()
{
var node = Nodes[0];
NumaNode node = Nodes[0];
Core core = node?.Cores[0];
CpuId cpu = core?.Threads[0];
if (cpu == null)
@@ -144,23 +147,49 @@ namespace LibreHardwareMonitor.Hardware.CPU
// THM_TCON_CUR_TMP
// CUR_TEMP [31:21]
Ring0.WritePciConfig(Ring0.GetPciAddress(0, 0, 0), FAMILY_17H_PCI_CONTROL_REGISTER, F17H_M01H_THM_TCON_CUR_TMP);
Ring0.ReadPciConfig(Ring0.GetPciAddress(0, 0, 0), FAMILY_17H_PCI_CONTROL_REGISTER + 4, out uint temperature);
Ring0.WritePciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER, F17H_M01H_THM_TCON_CUR_TMP);
Ring0.ReadPciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER + 4, out uint temperature);
// SVI0_TFN_PLANE0 [0]
// SVI0_TFN_PLANE1 [1]
Ring0.WritePciConfig(Ring0.GetPciAddress(0, 0, 0), FAMILY_17H_PCI_CONTROL_REGISTER, F17H_M01H_SVI + 0x8);
Ring0.ReadPciConfig(Ring0.GetPciAddress(0, 0, 0), FAMILY_17H_PCI_CONTROL_REGISTER + 4, out uint smuSvi0Tfn);
Ring0.WritePciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER, F17H_M01H_SVI + 0x8);
Ring0.ReadPciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER + 4, out uint smuSvi0Tfn);
uint sviPlane0Offset;
uint sviPlane1Offset;
// TODO: find a better way because these will probably keep changing in the future.
switch (cpu.Model)
{
case 0x31: // Threadripper 3000.
{
sviPlane0Offset = F17H_M01H_SVI + 0x14;
sviPlane1Offset = F17H_M01H_SVI + 0x10;
break;
}
case 0x71: // Zen 2.
{
sviPlane0Offset = F17H_M01H_SVI + 0x10;
sviPlane1Offset = F17H_M01H_SVI + 0xC;
break;
}
default: // Zen and Zen+.
{
sviPlane0Offset = F17H_M01H_SVI + 0xC;
sviPlane1Offset = F17H_M01H_SVI + 0x10;
break;
}
}
// SVI0_PLANE0_VDDCOR [24:16]
// SVI0_PLANE0_IDDCOR [7:0]
Ring0.WritePciConfig(Ring0.GetPciAddress(0, 0, 0), FAMILY_17H_PCI_CONTROL_REGISTER, F17H_M01H_SVI + 0xc);
Ring0.ReadPciConfig(Ring0.GetPciAddress(0, 0, 0), FAMILY_17H_PCI_CONTROL_REGISTER + 4, out uint smuSvi0TelPlane0);
Ring0.WritePciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER, sviPlane0Offset);
Ring0.ReadPciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER + 4, out uint smuSvi0TelPlane0);
// SVI0_PLANE1_VDDCOR [24:16]
// SVI0_PLANE1_IDDCOR [7:0]
Ring0.WritePciConfig(Ring0.GetPciAddress(0, 0, 0), FAMILY_17H_PCI_CONTROL_REGISTER, F17H_M01H_SVI + 0x10);
Ring0.ReadPciConfig(Ring0.GetPciAddress(0, 0, 0), FAMILY_17H_PCI_CONTROL_REGISTER + 4, out uint smuSvi0TelPlane1);
Ring0.WritePciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER, sviPlane1Offset);
Ring0.ReadPciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER + 4, out uint smuSvi0TelPlane1);
Ring0.ThreadAffinitySet(mask);
@@ -212,27 +241,92 @@ namespace LibreHardwareMonitor.Hardware.CPU
if (tempOffsetFlag)
t += -49.0f;
_coreTemperatureTctl.Value = t;
_coreTemperatureTdie.Value = t + offset;
if (offset < 0)
{
_coreTemperatureTctl.Value = t;
_coreTemperatureTdie.Value = t + offset;
_hw.ActivateSensor(_coreTemperatureTctl);
_hw.ActivateSensor(_coreTemperatureTdie);
}
else
{
// Zen 2 doesn't have an offset so Tdie and Tctl are the same.
_coreTemperatureTctlTdie.Value = t;
_hw.ActivateSensor(_coreTemperatureTctlTdie);
}
// Tested only on R5 3600 & Threadripper 3960X.
for (uint i = 0; i < _ccdTemperatures.Length; i++)
{
Ring0.WritePciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER, F17H_M70H_CCD1_TEMP + (i * 0x4));
Ring0.ReadPciConfig(0x00, FAMILY_17H_PCI_CONTROL_REGISTER + 4, out uint ccdTempData);
uint ccdTemp = ccdTempData & 0xFFF;
if (ccdTemp == 0)
continue;
if (_ccdTemperatures[i] == null)
{
_hw.ActivateSensor(_ccdTemperatures[i] = new Sensor(
$"Core CCD{i + 1} (Tdie)",
_hw._sensorTemperatures++,
SensorType.Temperature,
_hw,
_hw._settings));
}
_ccdTemperatures[i].Value = ((ccdTemp * 125) - 305000) * 0.001f;
}
Sensor[] activeCcds = _ccdTemperatures.Where(x => x != null).ToArray();
if (activeCcds.Length > 1)
{
// No need to get the max / average ccds temp if there is only one CCD.
if (_ccdsMaxTemperature == null)
{
_hw.ActivateSensor(_ccdsMaxTemperature = new Sensor(
"Core CCDs Max (Tdie)",
_hw._sensorTemperatures++,
SensorType.Temperature,
_hw,
_hw._settings));
}
if (_ccdsAverageTemperature == null)
{
_hw.ActivateSensor(_ccdsAverageTemperature = new Sensor(
"Core CCDs Average (Tdie)",
_hw._sensorTemperatures++,
SensorType.Temperature,
_hw,
_hw._settings));
}
_ccdsMaxTemperature.Value = activeCcds.Max(x => x.Value);
_ccdsAverageTemperature.Value = activeCcds.Average(x => x.Value);
}
// voltage
double vidStep = 0.00625;
const double vidStep = 0.00625;
double vcc;
uint svi0PlaneXVddCor;
// Core
// Core (0x01).
if ((smuSvi0Tfn & 0x01) == 0)
{
svi0PlaneXVddCor = ((cpu.Model == 0x71 ? smuSvi0TelPlane1 : smuSvi0TelPlane0) >> 16) & 0xff;
svi0PlaneXVddCor = (smuSvi0TelPlane0 >> 16) & 0xff;
vcc = 1.550 - vidStep * svi0PlaneXVddCor;
_coreVoltage.Value = (float)vcc;
_hw.ActivateSensor(_coreVoltage);
}
// SoC
// not every zen cpu has this voltage
if (cpu.Model == 0x71 || (smuSvi0Tfn & 0x02) == 0)
// SoC (0x02), not every Zen cpu has this voltage.
if (cpu.Model == 0x71 || cpu.Model == 0x31 || (smuSvi0Tfn & 0x02) == 0)
{
svi0PlaneXVddCor = ((cpu.Model == 0x71 ? smuSvi0TelPlane0 : smuSvi0TelPlane1) >> 16) & 0xff;
svi0PlaneXVddCor = (smuSvi0TelPlane1 >> 16) & 0xff;
vcc = 1.550 - vidStep * svi0PlaneXVddCor;
_socVoltage.Value = (float)vcc;
@@ -243,7 +337,7 @@ namespace LibreHardwareMonitor.Hardware.CPU
public void AppendThread(CpuId thread, int numaId, int coreId)
{
NumaNode node = null;
foreach (var n in Nodes)
foreach (NumaNode n in Nodes)
{
if (n.NodeId == numaId)
{
@@ -281,7 +375,7 @@ namespace LibreHardwareMonitor.Hardware.CPU
public void AppendThread(CpuId thread, int coreId)
{
Core core = null;
foreach (var c in Cores)
foreach (Core c in Cores)
{
if (c.CoreId == coreId)
core = c;
@@ -420,6 +514,7 @@ namespace LibreHardwareMonitor.Hardware.CPU
private const uint COFVID_STATUS = 0xC0010071;
private const uint F17H_M01H_SVI = 0x0005A000;
private const uint F17H_M01H_THM_TCON_CUR_TMP = 0x00059800;
private const uint F17H_M70H_CCD1_TEMP = 0x00059954;
private const uint F17H_TEMP_OFFSET_FLAG = 0x80000;
private const uint FAMILY_17H_PCI_CONTROL_REGISTER = 0x60;
private const uint HWCR = 0xC0010015;
+24 -16
View File
@@ -37,6 +37,7 @@ namespace LibreHardwareMonitor.Hardware
IsDefaultHidden = defaultHidden;
SensorType = sensorType;
_hardware = hardware;
Parameter[] parameters = new Parameter[parameterDescriptions?.Length ?? 0];
for (int i = 0; i < parameters.Length; i++)
{
@@ -166,29 +167,30 @@ namespace LibreHardwareMonitor.Hardware
private void SetSensorValuesToSettings()
{
using (MemoryStream m = new MemoryStream())
using (MemoryStream memoryStream = new MemoryStream())
{
using (GZipStream c = new GZipStream(m, CompressionMode.Compress))
using (GZipStream gZipStream = new GZipStream(memoryStream, CompressionMode.Compress))
{
using (BufferedStream b = new BufferedStream(c, 65536))
using (BufferedStream outputStream = new BufferedStream(gZipStream, 65536))
{
using (BinaryWriter writer = new BinaryWriter(b))
using (BinaryWriter binaryWriter = new BinaryWriter(outputStream))
{
long t = 0;
foreach (SensorValue sensorValue in _values)
{
long v = sensorValue.Time.ToBinary();
writer.Write(v - t);
binaryWriter.Write(v - t);
t = v;
writer.Write(sensorValue.Value);
binaryWriter.Write(sensorValue.Value);
}
writer.Flush();
binaryWriter.Flush();
}
}
}
_settings.SetValue(new Identifier(Identifier, "values").ToString(), Convert.ToBase64String(m.ToArray()));
_settings.SetValue(new Identifier(Identifier, "values").ToString(), Convert.ToBase64String(memoryStream.ToArray()));
}
}
@@ -203,20 +205,23 @@ namespace LibreHardwareMonitor.Hardware
{
byte[] array = Convert.FromBase64String(s);
DateTime now = DateTime.UtcNow;
using (MemoryStream m = new MemoryStream(array))
using (GZipStream c = new GZipStream(m, CompressionMode.Decompress))
using (MemoryStream memoryStream = new MemoryStream(array))
{
using (GZipStream gZipStream = new GZipStream(memoryStream, CompressionMode.Decompress))
{
using (MemoryStream unzip = new MemoryStream())
using (MemoryStream destination = new MemoryStream())
{
c.CopyTo(unzip);
unzip.Seek(0, SeekOrigin.Begin);
using (BinaryReader reader = new BinaryReader(unzip))
gZipStream.CopyTo(destination);
destination.Seek(0, SeekOrigin.Begin);
using (BinaryReader reader = new BinaryReader(destination))
{
try
{
long t = 0;
long readLen = reader.BaseStream.Length - reader.BaseStream.Position;
while (true && readLen > 0)
while (readLen > 0)
{
t += reader.ReadInt64();
DateTime time = DateTime.FromBinary(t);
@@ -234,9 +239,12 @@ namespace LibreHardwareMonitor.Hardware
}
}
}
}
}
catch
{ }
{
// Ignored.
}
}
if (_values.Count > 0)