diff --git a/.travis.yml b/.travis.yml index 8b496cd2..764c7d51 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ language: csharp solution: NoteBookFanControl.sln script: - - xbuild /t:Build /p:Configuration=ReleaseLinux NoteBookFanControl.sln \ No newline at end of file + - msbuild /t:Clean,Build /p:Configuration=ReleaseLinux NoteBookFanControl.sln diff --git a/Core/Plugins/OpenHardwareMonitor/Hardware/CPU/AMD10CPU.cs b/Core/Plugins/OpenHardwareMonitor/Hardware/CPU/AMD10CPU.cs index 10627123..f5fb1a3b 100644 --- a/Core/Plugins/OpenHardwareMonitor/Hardware/CPU/AMD10CPU.cs +++ b/Core/Plugins/OpenHardwareMonitor/Hardware/CPU/AMD10CPU.cs @@ -38,12 +38,16 @@ internal sealed class AMD10CPU : AMDCPU { private const ushort FAMILY_15H_MODEL_00_MISC_CONTROL_DEVICE_ID = 0x1603; private const ushort FAMILY_15H_MODEL_10_MISC_CONTROL_DEVICE_ID = 0x1403; private const ushort FAMILY_15H_MODEL_30_MISC_CONTROL_DEVICE_ID = 0x141D; + private const ushort FAMILY_15H_MODEL_60_MISC_CONTROL_DEVICE_ID = 0x1573; private const ushort FAMILY_16H_MODEL_00_MISC_CONTROL_DEVICE_ID = 0x1533; private const ushort FAMILY_16H_MODEL_30_MISC_CONTROL_DEVICE_ID = 0x1583; + private const ushort FAMILY_17H_MODEL_00_MISC_CONTROL_DEVICE_ID = 0x1577; private const uint REPORTED_TEMPERATURE_CONTROL_REGISTER = 0xA4; private const uint CLOCK_POWER_TIMING_CONTROL_0_REGISTER = 0xD4; + private const uint F15H_M60H_REPORTED_TEMP_CTRL_OFFSET = 0xD8200CA4; + private readonly uint miscellaneousControlAddress; private readonly ushort miscellaneousControlDeviceId; @@ -79,6 +83,8 @@ public AMD10CPU(int processorIndex, CPUID[][] cpuid, ISettings settings) FAMILY_15H_MODEL_10_MISC_CONTROL_DEVICE_ID; break; case 0x30: miscellaneousControlDeviceId = FAMILY_15H_MODEL_30_MISC_CONTROL_DEVICE_ID; break; + case 0x60: miscellaneousControlDeviceId = + FAMILY_15H_MODEL_60_MISC_CONTROL_DEVICE_ID; break; default: miscellaneousControlDeviceId = 0; break; } break; case 0x16: @@ -89,6 +95,8 @@ public AMD10CPU(int processorIndex, CPUID[][] cpuid, ISettings settings) FAMILY_16H_MODEL_30_MISC_CONTROL_DEVICE_ID; break; default: miscellaneousControlDeviceId = 0; break; } break; + case 0x17: miscellaneousControlDeviceId = + FAMILY_17H_MODEL_00_MISC_CONTROL_DEVICE_ID; break; default: miscellaneousControlDeviceId = 0; break; } @@ -136,8 +144,8 @@ public AMD10CPU(int processorIndex, CPUID[][] cpuid, ISettings settings) // the file reader for lm-sensors support on Linux temperatureStream = null; - int p = (int)Environment.OSVersion.Platform; - if ((p == 4) || (p == 128)) { + + if (Software.OperatingSystem.IsLinux) { string[] devicePaths = Directory.GetDirectories("/sys/class/hwmon/"); foreach (string path in devicePaths) { string name = null; @@ -304,6 +312,15 @@ public override void Update() { if (temperatureStream == null) { if (miscellaneousControlAddress != Ring0.InvalidPciAddress) { uint value; + if (miscellaneousControlAddress == FAMILY_15H_MODEL_60_MISC_CONTROL_DEVICE_ID) { + value = F15H_M60H_REPORTED_TEMP_CTRL_OFFSET; + Ring0.WritePciConfig(Ring0.GetPciAddress(0, 0, 0), 0xB8, value); + Ring0.ReadPciConfig(Ring0.GetPciAddress(0, 0, 0), 0xBC, out value); + coreTemperature.Value = ((value >> 21) & 0x7FF) * 0.125f + + coreTemperature.Parameters[0].Value; + ActivateSensor(coreTemperature); + return; + } if (Ring0.ReadPciConfig(miscellaneousControlAddress, REPORTED_TEMPERATURE_CONTROL_REGISTER, out value)) { if (family == 0x15 && (value & 0x30000) == 0x30000) { @@ -345,7 +362,7 @@ public override void Update() { Thread.Sleep(1); uint curEax, curEdx; - if (Ring0.Rdmsr(COFVID_STATUS, out curEax, out curEdx, cpuid[i][0].Thread)) + if (Ring0.Rdmsr(COFVID_STATUS, out curEax, out curEdx, cpuid[i][0].Thread)) { double multiplier; multiplier = GetCoreMultiplier(curEax); diff --git a/Core/Plugins/OpenHardwareMonitor/Hardware/CPU/AMD17CPU.cs b/Core/Plugins/OpenHardwareMonitor/Hardware/CPU/AMD17CPU.cs new file mode 100644 index 00000000..98e6d6c9 --- /dev/null +++ b/Core/Plugins/OpenHardwareMonitor/Hardware/CPU/AMD17CPU.cs @@ -0,0 +1,491 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// Copyright (C) 2016-2017 Sebastian Grams +// Copyright (C) 2016-2017 Aqua Computer + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.IO; +using System.Text; +using System.Threading; + +namespace OpenHardwareMonitor.Hardware.CPU +{ + internal sealed class AMD17CPU : AMDCPU + { + // counter, to create sensor index values + private int _sensorTemperatures = 0; + private int _sensorPower = 0; + private int _sensorVoltage = 0; + private int _sensorClock = 0; + private int _sensorMulti = 0; + + // register index names for CPUID[] + private const int EAX = 0; + private const int EBX = 1; + private const int ECX = 2; + private const int EDX = 3; + + #region amd zen registers + private const uint PERF_CTL_0 = 0xC0010000; + private const uint PERF_CTR_0 = 0xC0010004; + private const uint HWCR = 0xC0010015; + + private const uint MSR_PSTATE_L = 0xC0010061; + private const uint MSR_PSTATE_C = 0xC0010062; + private const uint MSR_PSTATE_S = 0xC0010063; + private const uint MSR_PSTATE_0 = 0xC0010064; + + private const uint MSR_PWR_UNIT = 0xC0010299; + private const uint MSR_CORE_ENERGY_STAT = 0xC001029A; + private const uint MSR_PKG_ENERGY_STAT = 0xC001029B; + private const uint MSR_HARDWARE_PSTATE_STATUS = 0xC0010293; + private const uint COFVID_STATUS = 0xC0010071; + private const uint FAMILY_17H_PCI_CONTROL_REGISTER = 0x60; + private const uint FAMILY_17H_MODEL_01_MISC_CONTROL_DEVICE_ID = 0x1463; + private const uint F17H_M01H_THM_TCON_CUR_TMP = 0x00059800; + private const uint F17H_M01H_SVI = 0x0005A000; + + public const uint F17H_TEMP_OFFSET_FLAG = 0x80000; + #endregion + + #region Processor + private class Processor + { + private AMD17CPU _hw = null; + private DateTime _lastPwrTime = new DateTime(0); + private uint _lastPwrValue = 0; + private Sensor _packagePower = null; + private Sensor _coreTemperatureTctl = null; + private Sensor _coreTemperatureTdie = null; + private Sensor _coreVoltage = null; + private Sensor _socVoltage = null; + public List Nodes { get; private set; } + + public Processor(Hardware hw) + { + this._hw = (AMD17CPU)hw; + Nodes = new List(); + + _packagePower = new Sensor("Package Power", this._hw._sensorPower++, SensorType.Power, this._hw, this._hw.settings); + _coreTemperatureTctl = new Sensor("Core (Tctl)", this._hw._sensorTemperatures++, SensorType.Temperature, this._hw, this._hw.settings); + _coreTemperatureTdie = new Sensor("Core (Tdie)", this._hw._sensorTemperatures++, SensorType.Temperature, this._hw, this._hw.settings); + _coreVoltage = new Sensor("Core (SVI2)", this._hw._sensorVoltage++, SensorType.Voltage, this._hw, this._hw.settings); + _socVoltage = new Sensor("SoC (SVI2)", this._hw._sensorVoltage++, SensorType.Voltage, this._hw, this._hw.settings); + + _hw.ActivateSensor(_packagePower); + _hw.ActivateSensor(_coreTemperatureTctl); + _hw.ActivateSensor(_coreTemperatureTdie); + _hw.ActivateSensor(_coreVoltage); + } + + #region UpdateSensors + public void UpdateSensors() + { + var node = Nodes[0]; + if (node == null) + return; + Core core = node.Cores[0]; + if (core == null) + return; + CPUID cpu = core.Threads[0]; + if (cpu == null) + return; + uint eax, edx; + + ulong mask = Ring0.ThreadAffinitySet(1UL << cpu.Thread); + + // MSRC001_0299 + // TU [19:16] + // ESU [12:8] -> Unit 15.3 micro Joule per increment + // PU [3:0] + Ring0.Rdmsr(MSR_PWR_UNIT, out eax, out edx); + int tu = (int)((eax >> 16) & 0xf); + int esu = (int)((eax >> 12) & 0xf); + int pu = (int)(eax & 0xf); + + // MSRC001_029B + // total_energy [31:0] + DateTime sample_time = DateTime.Now; + Ring0.Rdmsr(MSR_PKG_ENERGY_STAT, out eax, out edx); + uint total_energy = eax; + + // THM_TCON_CUR_TMP + // CUR_TEMP [31:21] + uint temperature = 0; + 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 temperature); + + // SVI0_TFN_PLANE0 [0] + // SVI0_TFN_PLANE1 [1] + uint smusvi0_tfn = 0; + 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 smusvi0_tfn); + + // SVI0_PLANE0_VDDCOR [24:16] + // SVI0_PLANE0_IDDCOR [7:0] + uint smusvi0_tel_plane0 = 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 smusvi0_tel_plane0); + + // SVI0_PLANE1_VDDCOR [24:16] + // SVI0_PLANE1_IDDCOR [7:0] + uint smusvi0_tel_plane1 = 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 smusvi0_tel_plane1); + + Ring0.ThreadAffinitySet(mask); + + // power consumption + // power.Value = (float) ((double)pu * 0.125); + // esu = 15.3 micro Joule per increment + if (_lastPwrTime.Ticks == 0) + { + _lastPwrTime = sample_time; + _lastPwrValue = total_energy; + } + // ticks diff + TimeSpan time = sample_time - _lastPwrTime; + long pwr; + if (_lastPwrValue <= total_energy) + pwr = total_energy - _lastPwrValue; + else + pwr = (0xffffffff - _lastPwrValue) + total_energy; + + // update for next sample + _lastPwrTime = sample_time; + _lastPwrValue = total_energy; + + double energy = 15.3e-6 * pwr; + energy /= time.TotalSeconds; + + _packagePower.Value = (float)energy; + + // current temp Bit [31:21] + //If bit 19 of the Temperature Control register is set, there is an additional offset of 49 degrees C. + bool temp_offset_flag = false; + if ((temperature & F17H_TEMP_OFFSET_FLAG) != 0) + temp_offset_flag = true; + temperature = (temperature >> 21) * 125; + + float offset = 0.0f; + if (cpu.Name != null && (cpu.Name.Contains("2600X") || cpu.Name.Contains("2700X"))) + offset = -10.0f; + if (cpu.Name != null && (cpu.Name.Contains("1600X") || cpu.Name.Contains("1700X") || cpu.Name.Contains("1800X"))) + offset = -20.0f; + else if (cpu.Name != null && (cpu.Name.Contains("1920X") || cpu.Name.Contains("1950X") || cpu.Name.Contains("1900X"))) + offset = -27.0f; + else if (cpu.Name != null && (cpu.Name.Contains("1910") || cpu.Name.Contains("1920") || cpu.Name.Contains("1950"))) + offset = -10.0f; + + float t = (temperature * 0.001f); + if (temp_offset_flag) + t += -49.0f; + + _coreTemperatureTctl.Value = t; + _coreTemperatureTdie.Value = t + offset; + + // voltage + double VIDStep = 0.00625; + double vcc; + uint svi0_plane_x_vddcor; + uint svi0_plane_x_iddcor; + + //Core + if ((smusvi0_tfn & 0x01) == 0) + { + svi0_plane_x_vddcor = (smusvi0_tel_plane0 >> 16) & 0xff; + svi0_plane_x_iddcor = smusvi0_tel_plane0 & 0xff; + vcc = 1.550 - (double)VIDStep * svi0_plane_x_vddcor; + _coreVoltage.Value = (float)vcc; + } + + // SoC + // not every zen cpu has this voltage + if ((smusvi0_tfn & 0x02) == 0) + { + svi0_plane_x_vddcor = (smusvi0_tel_plane1 >> 16) & 0xff; + svi0_plane_x_iddcor = smusvi0_tel_plane1 & 0xff; + vcc = 1.550 - (double)VIDStep * svi0_plane_x_vddcor; + _socVoltage.Value = (float)vcc; + _hw.ActivateSensor(_socVoltage); + } + + } + #endregion + + public void AppendThread(CPUID thread, int numa_id, int core_id) + { + NumaNode node = null; + foreach (var n in Nodes) + { + if (n.NodeId == numa_id) + node = n; + } + if (node == null) + { + node = new NumaNode(_hw, numa_id); + Nodes.Add(node); + } + if (thread != null) + node.AppendThread(thread, core_id); + } + } + #endregion + + #region NumaNode + private class NumaNode + { + private AMD17CPU _hw = null; + public int NodeId { get; private set; } + public List Cores { get; private set; } + + public NumaNode(Hardware hw, int id) + { + Cores = new List(); + NodeId = id; + _hw = (AMD17CPU)hw; + } + + public void AppendThread(CPUID thread, int core_id) + { + Core core = null; + foreach (var c in Cores) + { + if (c.CoreId == core_id) + core = c; + } + if (core == null) + { + core = new Core(_hw, core_id); + Cores.Add(core); + } + if (thread != null) + core.Threads.Add(thread); + } + + #region UpdateSensors + public void UpdateSensors() + { + } + #endregion + } + #endregion + + #region Core + private class Core + { + private DateTime _lastPwrTime = new DateTime(0); + private uint _lastPwrValue = 0; + private AMD17CPU _hw = null; + private Sensor _clock = null; + private Sensor _vcore = null; + private Sensor _power = null; + private Sensor _multiplier = null; + public int CoreId { get; private set; } + public List Threads { get; private set; } + + public Core(Hardware hw, int id) + { + Threads = new List(); + CoreId = id; + _hw = (AMD17CPU)hw; + _clock = new Sensor("Core #" + CoreId.ToString(), _hw._sensorClock++, SensorType.Clock, _hw, _hw.settings); + _multiplier = new Sensor("Core #" + CoreId.ToString(), _hw._sensorMulti++, SensorType.Factor, _hw, _hw.settings); + _power = new Sensor("Core #" + CoreId.ToString() + " (SMU)", _hw._sensorPower++, SensorType.Power, _hw, _hw.settings); + _vcore = new Sensor("Core #" + CoreId.ToString() + " VID", _hw._sensorVoltage++, SensorType.Voltage, _hw, _hw.settings); + + _hw.ActivateSensor(_clock); + _hw.ActivateSensor(_multiplier); + _hw.ActivateSensor(_power); + _hw.ActivateSensor(_vcore); + } + + #region UpdateSensors + public void UpdateSensors() + { + // CPUID cpu = threads.FirstOrDefault(); + CPUID cpu = Threads[0]; + if (cpu == null) + return; + uint eax, edx; + ulong mask = Ring0.ThreadAffinitySet(1UL << cpu.Thread); + + // MSRC001_0299 + // TU [19:16] + // ESU [12:8] -> Unit 15.3 micro Joule per increment + // PU [3:0] + Ring0.Rdmsr(MSR_PWR_UNIT, out eax, out edx); + int tu = (int)((eax >> 16) & 0xf); + int esu = (int)((eax >> 12) & 0xf); + int pu = (int)(eax & 0xf); + + // MSRC001_029A + // total_energy [31:0] + DateTime sample_time = DateTime.Now; + Ring0.Rdmsr(MSR_CORE_ENERGY_STAT, out eax, out edx); + uint total_energy = eax; + + // MSRC001_0293 + // CurHwPstate [24:22] + // CurCpuVid [21:14] + // CurCpuDfsId [13:8] + // CurCpuFid [7:0] + Ring0.Rdmsr(MSR_HARDWARE_PSTATE_STATUS, out eax, out edx); + int CurHwPstate = (int)((eax >> 22) & 0x3); + int CurCpuVid = (int)((eax >> 14) & 0xff); + int CurCpuDfsId = (int)((eax >> 8) & 0x3f); + int CurCpuFid = (int)(eax & 0xff); + + // MSRC001_0064 + x + // IddDiv [31:30] + // IddValue [29:22] + // CpuVid [21:14] + // CpuDfsId [13:8] + // CpuFid [7:0] + // Ring0.Rdmsr(MSR_PSTATE_0 + (uint)CurHwPstate, out eax, out edx); + // int IddDiv = (int)((eax >> 30) & 0x03); + // int IddValue = (int)((eax >> 22) & 0xff); + // int CpuVid = (int)((eax >> 14) & 0xff); + Ring0.ThreadAffinitySet(mask); + + // clock + // CoreCOF is (Core::X86::Msr::PStateDef[CpuFid[7:0]] / Core::X86::Msr::PStateDef[CpuDfsId]) * 200 + _clock.Value = (float)((double)CurCpuFid / (double)CurCpuDfsId * 200.0); + + // multiplier + _multiplier.Value = (float)((double)CurCpuFid / (double)CurCpuDfsId * 2.0); + + // Voltage + double VIDStep = 0.00625; + double vcc = 1.550 - (double)VIDStep * CurCpuVid; + _vcore.Value = (float)vcc; + + // power consumption + // power.Value = (float) ((double)pu * 0.125); + // esu = 15.3 micro Joule per increment + if (_lastPwrTime.Ticks == 0) + { + _lastPwrTime = sample_time; + _lastPwrValue = total_energy; + } + // ticks diff + TimeSpan time = sample_time - _lastPwrTime; + long pwr; + if (_lastPwrValue <= total_energy) + pwr = total_energy - _lastPwrValue; + else + pwr = (0xffffffff - _lastPwrValue) + total_energy; + + // update for next sample + _lastPwrTime = sample_time; + _lastPwrValue = total_energy; + + double energy = 15.3e-6 * pwr; + energy /= time.TotalSeconds; + + _power.Value = (float)energy; + } + #endregion + } + #endregion + + private Processor _ryzen = null; + + public AMD17CPU(int processorIndex, CPUID[][] cpuid, ISettings settings) + : base(processorIndex, cpuid, settings) + { + // add all numa nodes + // Register ..1E_ECX, [10:8] + 1 + _ryzen = new Processor(this); + int NodesPerProcessor = 1 + (int)((cpuid[0][0].ExtData[0x1e, ECX] >> 8) & 0x7); + + // add all numa nodes + foreach (CPUID[] cpu in cpuid) + { + CPUID thread = cpu[0]; + + // coreID + // Register ..1E_EBX, [7:0] + int core_id = (int)(thread.ExtData[0x1e, EBX] & 0xff); + + // nodeID + // Register ..1E_ECX, [7:0] + int node_id = (int)(thread.ExtData[0x1e, ECX] & 0xff); + + _ryzen.AppendThread(null, node_id, core_id); + } + + // add all threads to numa nodes and specific core + foreach (CPUID[] cpu in cpuid) + { + CPUID thread = cpu[0]; + + // coreID + // Register ..1E_EBX, [7:0] + int core_id = (int)(thread.ExtData[0x1e, EBX] & 0xff); + + // nodeID + // Register ..1E_ECX, [7:0] + int node_id = (int)(thread.ExtData[0x1e, ECX] & 0xff); + + _ryzen.AppendThread(thread, node_id, core_id); + } + Update(); + } + + protected override uint[] GetMSRs() + { + return new uint[] { PERF_CTL_0, PERF_CTR_0, HWCR, MSR_PSTATE_0, COFVID_STATUS }; + } + + public override string GetReport() + { + StringBuilder r = new StringBuilder(); + r.Append(base.GetReport()); + r.Append("Ryzen"); + return r.ToString(); + } + + private string ReadFirstLine(Stream stream) + { + StringBuilder sb = new StringBuilder(); + try + { + stream.Seek(0, SeekOrigin.Begin); + int b = stream.ReadByte(); + while (b != -1 && b != 10) + { + sb.Append((char)b); + b = stream.ReadByte(); + } + } + catch { } + return sb.ToString(); + } + + public override void Update() + { + base.Update(); + + _ryzen.UpdateSensors(); + foreach (NumaNode node in _ryzen.Nodes) + { + node.UpdateSensors(); + + foreach (Core c in node.Cores) + { + c.UpdateSensors(); + } + } + } + + public override void Close() + { + base.Close(); + } + } +} diff --git a/Core/Plugins/OpenHardwareMonitor/Hardware/CPU/CPUGroup.cs b/Core/Plugins/OpenHardwareMonitor/Hardware/CPU/CPUGroup.cs index 74295500..7373a466 100644 --- a/Core/Plugins/OpenHardwareMonitor/Hardware/CPU/CPUGroup.cs +++ b/Core/Plugins/OpenHardwareMonitor/Hardware/CPU/CPUGroup.cs @@ -104,6 +104,9 @@ public CPUGroup(ISettings settings) { case 0x16: hardware.Add(new AMD10CPU(index, coreThreads, settings)); break; + case 0x17: + hardware.Add(new AMD17CPU(index, coreThreads, settings)); + break; default: hardware.Add(new GenericCPU(index, coreThreads, settings)); break; diff --git a/Core/Plugins/OpenHardwareMonitor/Hardware/CPU/CPUID.cs b/Core/Plugins/OpenHardwareMonitor/Hardware/CPU/CPUID.cs index e418dc40..fed0aa50 100644 --- a/Core/Plugins/OpenHardwareMonitor/Hardware/CPU/CPUID.cs +++ b/Core/Plugins/OpenHardwareMonitor/Hardware/CPU/CPUID.cs @@ -12,14 +12,13 @@ This Source Code Form is subject to the terms of the Mozilla Public using System.Text; namespace OpenHardwareMonitor.Hardware.CPU { - - internal enum Vendor { + public enum Vendor { Unknown, Intel, AMD, } - internal class CPUID { + public class CPUID { private readonly int thread; @@ -186,6 +185,27 @@ public CPUID(int thread) { corePerPackage = 1; threadMaskWith = 0; coreMaskWith = NextLog2(corePerPackage); + + if (this.family == 0x17) + { + // ApicIdCoreIdSize: APIC ID size. + // cores per DIE + // we need this for Ryzen 5 (4 cores, 8 threads) ans Ryzen 6 (6 cores, 12 threads) + // Ryzen 5: [core0][core1][dummy][dummy][core2][core3] (Core0 EBX = 00080800, Core2 EBX = 08080800) + uint max_cores_per_die = (cpuidExtData[8, 2] >> 12) & 0xF; + switch (max_cores_per_die) + { + case 0x04: // Ryzen + coreMaskWith = NextLog2(16); + break; + case 0x05:// Threadripper + coreMaskWith = NextLog2(32); + break; + case 0x06:// Epic + coreMaskWith = NextLog2(64); + break; + } + } break; default: threadMaskWith = 0; diff --git a/Core/Plugins/OpenHardwareMonitor/Hardware/CPU/IntelCPU.cs b/Core/Plugins/OpenHardwareMonitor/Hardware/CPU/IntelCPU.cs index b8584858..f6aa5ca7 100644 --- a/Core/Plugins/OpenHardwareMonitor/Hardware/CPU/IntelCPU.cs +++ b/Core/Plugins/OpenHardwareMonitor/Hardware/CPU/IntelCPU.cs @@ -28,7 +28,9 @@ private enum Microarchitecture { Silvermont, Skylake, Airmont, - KabyLake + KabyLake, + ApolloLake, + CoffeeLake } private readonly Sensor[] coreTemperatures; @@ -59,6 +61,7 @@ private enum Microarchitecture { private DateTime[] lastEnergyTime; private uint[] lastEnergyConsumed; + private float[] Floats(float f) { float[] result = new float[coreCount]; for (int i = 0; i < coreCount; i++) @@ -100,7 +103,6 @@ public IntelCPU(int processorIndex, CPUID[][] cpuid, ISettings settings) tjMax = Floats(85 + 10); break; } tjMax = Floats(80 + 10); break; - case 0x0A: // E1 case 0x0B: // G0 tjMax = Floats(90 + 10); break; case 0x0D: // M0 @@ -170,6 +172,7 @@ public IntelCPU(int processorIndex, CPUID[][] cpuid, ISettings settings) break; case 0x4E: case 0x5E: // Intel Core i5, i7 6xxxx LGA1151 (14nm) + case 0x55: // Intel Core X i7, i9 7xxx LGA2066 (14nm) microarchitecture = Microarchitecture.Skylake; tjMax = GetTjMaxFromMSR(); break; @@ -182,6 +185,14 @@ public IntelCPU(int processorIndex, CPUID[][] cpuid, ISettings settings) microarchitecture = Microarchitecture.KabyLake; tjMax = GetTjMaxFromMSR(); break; + case 0x5C: // Intel ApolloLake + microarchitecture = Microarchitecture.ApolloLake; + tjMax = GetTjMaxFromMSR(); + break; + case 0xAE: // Intel Core i5, i7 8xxxx (14nm++) + microarchitecture = Microarchitecture.CoffeeLake; + tjMax = GetTjMaxFromMSR(); + break; default: microarchitecture = Microarchitecture.Unknown; tjMax = Floats(100); @@ -230,7 +241,9 @@ public IntelCPU(int processorIndex, CPUID[][] cpuid, ISettings settings) case Microarchitecture.Silvermont: case Microarchitecture.Skylake: case Microarchitecture.Airmont: - case Microarchitecture.KabyLake: { + case Microarchitecture.ApolloLake: + case Microarchitecture.KabyLake: + case Microarchitecture.CoffeeLake: { uint eax, edx; if (Ring0.Rdmsr(MSR_PLATFORM_INFO, out eax, out edx)) { timeStampCounterMultiplier = (eax >> 8) & 0xff; @@ -294,7 +307,8 @@ public IntelCPU(int processorIndex, CPUID[][] cpuid, ISettings settings) microarchitecture == Microarchitecture.Skylake || microarchitecture == Microarchitecture.Silvermont || microarchitecture == Microarchitecture.Airmont || - microarchitecture == Microarchitecture.KabyLake) + microarchitecture == Microarchitecture.KabyLake || + microarchitecture == Microarchitecture.ApolloLake) { powerSensors = new Sensor[energyStatusMSRs.Length]; lastEnergyTime = new DateTime[energyStatusMSRs.Length]; @@ -397,8 +411,7 @@ public override void Update() { uint eax, edx; for (int i = 0; i < coreClocks.Length; i++) { System.Threading.Thread.Sleep(1); - if (Ring0.Rdmsr(IA32_PERF_STATUS, out eax, out edx, - cpuid[i][0].Thread)) { + if (Ring0.Rdmsr(IA32_PERF_STATUS, out eax, out edx, cpuid[i][0].Thread)) { newBusClock = TimeStampCounterFrequency / timeStampCounterMultiplier; switch (microarchitecture) { @@ -412,7 +425,9 @@ public override void Update() { case Microarchitecture.Broadwell: case Microarchitecture.Silvermont: case Microarchitecture.Skylake: - case Microarchitecture.KabyLake: { + case Microarchitecture.ApolloLake: + case Microarchitecture.KabyLake: + case Microarchitecture.CoffeeLake: { uint multiplier = (eax >> 8) & 0xff; coreClocks[i].Value = (float)(multiplier * newBusClock); } break; diff --git a/Core/Plugins/OpenHardwareMonitor/Hardware/Ring0.cs b/Core/Plugins/OpenHardwareMonitor/Hardware/Ring0.cs index ff6dbedb..9c9d7442 100644 --- a/Core/Plugins/OpenHardwareMonitor/Hardware/Ring0.cs +++ b/Core/Plugins/OpenHardwareMonitor/Hardware/Ring0.cs @@ -294,6 +294,10 @@ public static void Close() isaBusMutex = null; } } + public static ulong ThreadAffinitySet(ulong mask) + { + return ThreadAffinity.Set(mask); + } public static string GetReport() { diff --git a/Core/Plugins/OpenHardwareMonitor/OpenHardwareMonitorLib.csproj b/Core/Plugins/OpenHardwareMonitor/OpenHardwareMonitorLib.csproj index d24410e8..41f8de61 100644 --- a/Core/Plugins/OpenHardwareMonitor/OpenHardwareMonitorLib.csproj +++ b/Core/Plugins/OpenHardwareMonitor/OpenHardwareMonitorLib.csproj @@ -66,6 +66,7 @@ + @@ -125,6 +126,7 @@ + @@ -138,4 +140,4 @@ --> - \ No newline at end of file + diff --git a/Core/Plugins/OpenHardwareMonitor/Software/OperatingSystem.cs b/Core/Plugins/OpenHardwareMonitor/Software/OperatingSystem.cs new file mode 100644 index 00000000..1fa66acb --- /dev/null +++ b/Core/Plugins/OpenHardwareMonitor/Software/OperatingSystem.cs @@ -0,0 +1,37 @@ +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace OpenHardwareMonitor.Software { + public static class OperatingSystem { + static OperatingSystem() { + // The operating system doesn't change during execution so let's query it just one time. + var platform = Environment.OSVersion.Platform; + IsLinux = platform == PlatformID.Unix || platform == PlatformID.MacOSX; + + + if (IntPtr.Size == 8) { + Is64Bit = true; + } else if (!IsLinux) { + try { + var result = IsWow64Process(Process.GetCurrentProcess().Handle, out bool wow64Process); + // If we are still here, this is a 64bit windows; 32bit windows does + // not provide IsWow64Process. + Is64Bit = true; + } + catch (EntryPointNotFoundException) { + // IsWow64Process is not present on 32 bit: + Is64Bit = false; + } + } + } + + public static bool Is64Bit { get; } + + public static bool IsLinux { get; } + + [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool IsWow64Process(IntPtr hProcess, out bool wow64Process); + } +} \ No newline at end of file diff --git a/Windows/Setup/NbfcSetup/Configs.wxs b/Windows/Setup/NbfcSetup/Configs.wxs index 4c68e4b8..d8005a9f 100644 --- a/Windows/Setup/NbfcSetup/Configs.wxs +++ b/Windows/Setup/NbfcSetup/Configs.wxs @@ -230,6 +230,9 @@ + + + @@ -275,6 +278,9 @@ + + + @@ -290,6 +296,9 @@ + + + @@ -392,9 +401,15 @@ + + + + + + @@ -497,6 +512,9 @@ + + + \ No newline at end of file diff --git a/build.ps1 b/build.ps1 index 4aa57a13..86dc3e49 100644 --- a/build.ps1 +++ b/build.ps1 @@ -35,6 +35,6 @@ $path = & $vswhere -latest -products * -requires Microsoft.Component.MSBuild -pr $msbuild = join-path $path 'MSBuild\15.0\Bin\MSBuild.exe' # build solution -& $msbuild /t:Build /p:Configuration=ReleaseWindows NoteBookFanControl.sln +& $msbuild /t:Clean,Build /p:Configuration=ReleaseWindows NoteBookFanControl.sln pop-location diff --git a/build.sh b/build.sh index 584e0bdb..e29620bc 100755 --- a/build.sh +++ b/build.sh @@ -36,6 +36,6 @@ then fi # build solution -xbuild /t:Build /p:Configuration=ReleaseLinux NoteBookFanControl.sln +msbuild /t:Clean,Build /p:Configuration=ReleaseLinux NoteBookFanControl.sln popd