Files
2025-04-07 07:44:27 -07:00

732 lines
30 KiB
C#

// 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) LibreHardwareMonitor and Contributors.
// Partial Copyright (C) Michael Möller <mmoeller@openhardwaremonitor.org> and Contributors.
// All Rights Reserved.
using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Text;
namespace LibreHardwareMonitor.Hardware.Cpu;
internal sealed class IntelCpu : GenericCpu
{
private readonly Sensor _busClock;
private readonly Sensor _coreAvg;
private readonly Sensor[] _coreClocks;
private readonly Sensor _coreMax;
private readonly Sensor[] _coreTemperatures;
private readonly Sensor[] _coreVIDs;
private readonly Sensor _coreVoltage;
private readonly Sensor[] _distToTjMaxTemperatures;
private readonly uint[] _energyStatusMsrs = { MSR_PKG_ENERGY_STATUS, MSR_PP0_ENERGY_STATUS, MSR_PP1_ENERGY_STATUS, MSR_DRAM_ENERGY_STATUS, MSR_PLATFORM_ENERGY_STATUS };
private readonly uint[] _lastEnergyConsumed;
private readonly DateTime[] _lastEnergyTime;
private readonly MicroArchitecture _microArchitecture;
private readonly Sensor _packageTemperature;
private readonly Sensor[] _powerSensors;
private readonly double _timeStampCounterMultiplier;
public IntelCpu(int processorIndex, CpuId[][] cpuId, ISettings settings) : base(processorIndex, cpuId, settings)
{
uint eax;
// set tjMax
float[] tjMax;
switch (_family)
{
case 0x06:
{
switch (_model)
{
case 0x0F: // Intel Core 2 (65nm)
_microArchitecture = MicroArchitecture.Core;
tjMax = _stepping switch
{
// B2
0x06 => _coreCount switch
{
2 => Floats(80 + 10),
4 => Floats(90 + 10),
_ => Floats(85 + 10)
},
// G0
0x0B => Floats(90 + 10),
// M0
0x0D => Floats(85 + 10),
_ => Floats(85 + 10)
};
break;
case 0x17: // Intel Core 2 (45nm)
_microArchitecture = MicroArchitecture.Core;
tjMax = Floats(100);
break;
case 0x1C: // Intel Atom (45nm)
_microArchitecture = MicroArchitecture.Atom;
tjMax = _stepping switch
{
// C0
0x02 => Floats(90),
// A0, B0
0x0A => Floats(100),
_ => Floats(90)
};
break;
case 0x1A: // Intel Core i7 LGA1366 (45nm)
case 0x1E: // Intel Core i5, i7 LGA1156 (45nm)
case 0x1F: // Intel Core i5, i7
case 0x25: // Intel Core i3, i5, i7 LGA1156 (32nm)
case 0x2C: // Intel Core i7 LGA1366 (32nm) 6 Core
case 0x2E: // Intel Xeon Processor 7500 series (45nm)
case 0x2F: // Intel Xeon Processor (32nm)
_microArchitecture = MicroArchitecture.Nehalem;
tjMax = GetTjMaxFromMsr();
break;
case 0x2A: // Intel Core i5, i7 2xxx LGA1155 (32nm)
case 0x2D: // Next Generation Intel Xeon, i7 3xxx LGA2011 (32nm)
_microArchitecture = MicroArchitecture.SandyBridge;
tjMax = GetTjMaxFromMsr();
break;
case 0x3A: // Intel Core i5, i7 3xxx LGA1155 (22nm)
case 0x3E: // Intel Core i7 4xxx LGA2011 (22nm)
_microArchitecture = MicroArchitecture.IvyBridge;
tjMax = GetTjMaxFromMsr();
break;
case 0x3C: // Intel Core i5, i7 4xxx LGA1150 (22nm)
case 0x3F: // Intel Xeon E5-2600/1600 v3, Core i7-59xx
// LGA2011-v3, Haswell-E (22nm)
case 0x45: // Intel Core i5, i7 4xxxU (22nm)
case 0x46:
_microArchitecture = MicroArchitecture.Haswell;
tjMax = GetTjMaxFromMsr();
break;
case 0x3D: // Intel Core M-5xxx (14nm)
case 0x47: // Intel i5, i7 5xxx, Xeon E3-1200 v4 (14nm)
case 0x4F: // Intel Xeon E5-26xx v4
case 0x56: // Intel Xeon D-15xx
_microArchitecture = MicroArchitecture.Broadwell;
tjMax = GetTjMaxFromMsr();
break;
case 0x36: // Intel Atom S1xxx, D2xxx, N2xxx (32nm)
_microArchitecture = MicroArchitecture.Atom;
tjMax = GetTjMaxFromMsr();
break;
case 0x37: // Intel Atom E3xxx, Z3xxx (22nm)
case 0x4A:
case 0x4D: // Intel Atom C2xxx (22nm)
case 0x5A:
case 0x5D:
_microArchitecture = MicroArchitecture.Silvermont;
tjMax = GetTjMaxFromMsr();
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;
case 0x4C: // Intel Airmont (Cherry Trail, Braswell)
_microArchitecture = MicroArchitecture.Airmont;
tjMax = GetTjMaxFromMsr();
break;
case 0x8E: // Intel Core i5, i7 7xxxx (14nm) (Kaby Lake) and 8xxxx (14nm++) (Coffee Lake)
case 0x9E:
_microArchitecture = MicroArchitecture.KabyLake;
tjMax = GetTjMaxFromMsr();
break;
case 0x5C: // Goldmont (Apollo Lake)
case 0x5F: // (Denverton)
_microArchitecture = MicroArchitecture.Goldmont;
tjMax = GetTjMaxFromMsr();
break;
case 0x7A: // Goldmont plus (Gemini Lake)
_microArchitecture = MicroArchitecture.GoldmontPlus;
tjMax = GetTjMaxFromMsr();
break;
case 0x66: // Intel Core i3 8xxx (10nm) (Cannon Lake)
_microArchitecture = MicroArchitecture.CannonLake;
tjMax = GetTjMaxFromMsr();
break;
case 0x7D: // Intel Core i3, i5, i7 10xxx (10nm) (Ice Lake)
case 0x7E:
case 0x6A: // Ice Lake server
case 0x6C:
_microArchitecture = MicroArchitecture.IceLake;
tjMax = GetTjMaxFromMsr();
break;
case 0xA5:
case 0xA6: // Intel Core i3, i5, i7 10xxxU (14nm)
_microArchitecture = MicroArchitecture.CometLake;
tjMax = GetTjMaxFromMsr();
break;
case 0x86: // Tremont (10nm) (Elkhart Lake, Skyhawk Lake)
_microArchitecture = MicroArchitecture.Tremont;
tjMax = GetTjMaxFromMsr();
break;
case 0x8C: // Tiger Lake (Intel 10 nm SuperFin, Gen. 11)
case 0x8D:
_microArchitecture = MicroArchitecture.TigerLake;
tjMax = GetTjMaxFromMsr();
break;
case 0x97: // Alder Lake (Intel 7 (10ESF), Gen. 12)
case 0x9A: // Alder Lake-L (Intel 7 (10ESF), Gen. 12)
case 0xBE: // Alder Lake-N (Intel 7 (10ESF), Gen. 12)
_microArchitecture = MicroArchitecture.AlderLake;
tjMax = GetTjMaxFromMsr();
break;
case 0xB7: // Raptor Lake (Intel 7 (10ESF), Gen. 13)
case 0xBA: // Raptor Lake-P (Intel 7 (10ESF), Gen. 13)
case 0xBF: // Raptor Lake-N (Intel 7 (10ESF), Gen. 13)
_microArchitecture = MicroArchitecture.RaptorLake;
tjMax = GetTjMaxFromMsr();
break;
case 0xAC: // Meteor Lake (Intel 4, TSMC N5/N6, Gen. 14)
case 0xAA: // Meteor Lake-L (Intel 4, TSMC N5/N6, Gen. 14)
_microArchitecture = MicroArchitecture.MeteorLake;
tjMax = GetTjMaxFromMsr();
break;
case 0x9C: // Jasper Lake (10nm)
_microArchitecture = MicroArchitecture.JasperLake;
tjMax = GetTjMaxFromMsr();
break;
case 0xA7: // Intel Core i5, i6, i7 11xxx (14nm) (Rocket Lake)
_microArchitecture = MicroArchitecture.RocketLake;
tjMax = GetTjMaxFromMsr();
break;
case 0xC6: // Intel Core Ultra 7 200 Series ArrowLake
_microArchitecture = MicroArchitecture.ArrowLake;
tjMax = GetTjMaxFromMsr();
break;
case 0xBD: // Intel Core Ultra 5/7 200 Series LunarLake
_microArchitecture = MicroArchitecture.LunarLake;
tjMax = GetTjMaxFromMsr();
break;
default:
_microArchitecture = MicroArchitecture.Unknown;
tjMax = Floats(100);
break;
}
}
break;
case 0x0F:
switch (_model)
{
case 0x00: // Pentium 4 (180nm)
case 0x01: // Pentium 4 (130nm)
case 0x02: // Pentium 4 (130nm)
case 0x03: // Pentium 4, Celeron D (90nm)
case 0x04: // Pentium 4, Pentium D, Celeron D (90nm)
case 0x06: // Pentium 4, Pentium D, Celeron D (65nm)
_microArchitecture = MicroArchitecture.NetBurst;
tjMax = Floats(100);
break;
default:
_microArchitecture = MicroArchitecture.Unknown;
tjMax = Floats(100);
break;
}
break;
default:
_microArchitecture = MicroArchitecture.Unknown;
tjMax = Floats(100);
break;
}
// set timeStampCounterMultiplier
switch (_microArchitecture)
{
case MicroArchitecture.Atom:
case MicroArchitecture.Core:
case MicroArchitecture.NetBurst:
if (Ring0.ReadMsr(IA32_PERF_STATUS, out uint _, out uint edx))
_timeStampCounterMultiplier = ((edx >> 8) & 0x1f) + (0.5 * ((edx >> 14) & 1));
break;
case MicroArchitecture.Airmont:
case MicroArchitecture.AlderLake:
case MicroArchitecture.ArrowLake:
case MicroArchitecture.Broadwell:
case MicroArchitecture.CannonLake:
case MicroArchitecture.CometLake:
case MicroArchitecture.Goldmont:
case MicroArchitecture.GoldmontPlus:
case MicroArchitecture.Haswell:
case MicroArchitecture.IceLake:
case MicroArchitecture.IvyBridge:
case MicroArchitecture.JasperLake:
case MicroArchitecture.KabyLake:
case MicroArchitecture.LunarLake:
case MicroArchitecture.Nehalem:
case MicroArchitecture.MeteorLake:
case MicroArchitecture.RaptorLake:
case MicroArchitecture.RocketLake:
case MicroArchitecture.SandyBridge:
case MicroArchitecture.Silvermont:
case MicroArchitecture.Skylake:
case MicroArchitecture.TigerLake:
case MicroArchitecture.Tremont:
if (Ring0.ReadMsr(MSR_PLATFORM_INFO, out eax, out uint _))
_timeStampCounterMultiplier = (eax >> 8) & 0xff;
break;
default:
_timeStampCounterMultiplier = 0;
break;
}
int coreSensorId = 0;
//core temp avg and max value
//is only available when the cpu has more than 1 core
if (cpuId[0][0].Data.GetLength(0) > 6 && (cpuId[0][0].Data[6, 0] & 0x40) != 0 && _microArchitecture != MicroArchitecture.Unknown && _coreCount > 1)
{
_coreMax = new Sensor("Core Max", coreSensorId, SensorType.Temperature, this, settings);
ActivateSensor(_coreMax);
coreSensorId++;
_coreAvg = new Sensor("Core Average", coreSensorId, SensorType.Temperature, this, settings);
ActivateSensor(_coreAvg);
coreSensorId++;
}
else
{
_coreMax = null;
_coreAvg = null;
}
// check if processor supports a digital thermal sensor at core level
if (cpuId[0][0].Data.GetLength(0) > 6 && (cpuId[0][0].Data[6, 0] & 1) != 0 && _microArchitecture != MicroArchitecture.Unknown)
{
_coreTemperatures = new Sensor[_coreCount];
for (int i = 0; i < _coreTemperatures.Length; i++)
{
_coreTemperatures[i] = new Sensor(CoreString(i),
coreSensorId,
SensorType.Temperature,
this,
new[]
{
new ParameterDescription("TjMax [°C]", "TjMax temperature of the core sensor.\n" + "Temperature = TjMax - TSlope * Value.", tjMax[i]),
new ParameterDescription("TSlope [°C]", "Temperature slope of the digital thermal sensor.\n" + "Temperature = TjMax - TSlope * Value.", 1)
},
settings);
ActivateSensor(_coreTemperatures[i]);
coreSensorId++;
}
}
else
_coreTemperatures = Array.Empty<Sensor>();
// check if processor supports a digital thermal sensor at package level
if (cpuId[0][0].Data.GetLength(0) > 6 && (cpuId[0][0].Data[6, 0] & 0x40) != 0 && _microArchitecture != MicroArchitecture.Unknown)
{
_packageTemperature = new Sensor("CPU Package",
coreSensorId,
SensorType.Temperature,
this,
new[]
{
new ParameterDescription("TjMax [°C]", "TjMax temperature of the package sensor.\n" + "Temperature = TjMax - TSlope * Value.", tjMax[0]),
new ParameterDescription("TSlope [°C]", "Temperature slope of the digital thermal sensor.\n" + "Temperature = TjMax - TSlope * Value.", 1)
},
settings);
ActivateSensor(_packageTemperature);
coreSensorId++;
}
// dist to tjmax sensor
if (cpuId[0][0].Data.GetLength(0) > 6 && (cpuId[0][0].Data[6, 0] & 1) != 0 && _microArchitecture != MicroArchitecture.Unknown)
{
_distToTjMaxTemperatures = new Sensor[_coreCount];
for (int i = 0; i < _distToTjMaxTemperatures.Length; i++)
{
_distToTjMaxTemperatures[i] = new Sensor(CoreString(i) + " Distance to TjMax", coreSensorId, SensorType.Temperature, this, settings);
ActivateSensor(_distToTjMaxTemperatures[i]);
coreSensorId++;
}
}
else
_distToTjMaxTemperatures = Array.Empty<Sensor>();
_busClock = new Sensor("Bus Speed", 0, SensorType.Clock, this, settings);
_coreClocks = new Sensor[_coreCount];
for (int i = 0; i < _coreClocks.Length; i++)
{
_coreClocks[i] = new Sensor(CoreString(i), i + 1, SensorType.Clock, this, settings);
if (HasTimeStampCounter && _microArchitecture != MicroArchitecture.Unknown)
ActivateSensor(_coreClocks[i]);
}
if (_microArchitecture is MicroArchitecture.Airmont or
MicroArchitecture.AlderLake or
MicroArchitecture.ArrowLake or
MicroArchitecture.Broadwell or
MicroArchitecture.CannonLake or
MicroArchitecture.CometLake or
MicroArchitecture.Goldmont or
MicroArchitecture.GoldmontPlus or
MicroArchitecture.Haswell or
MicroArchitecture.IceLake or
MicroArchitecture.IvyBridge or
MicroArchitecture.JasperLake or
MicroArchitecture.KabyLake or
MicroArchitecture.LunarLake or
MicroArchitecture.MeteorLake or
MicroArchitecture.RaptorLake or
MicroArchitecture.RocketLake or
MicroArchitecture.SandyBridge or
MicroArchitecture.Silvermont or
MicroArchitecture.Skylake or
MicroArchitecture.TigerLake or
MicroArchitecture.Tremont)
{
_powerSensors = new Sensor[_energyStatusMsrs.Length];
_lastEnergyTime = new DateTime[_energyStatusMsrs.Length];
_lastEnergyConsumed = new uint[_energyStatusMsrs.Length];
if (Ring0.ReadMsr(MSR_RAPL_POWER_UNIT, out eax, out uint _))
{
EnergyUnitsMultiplier = _microArchitecture switch
{
MicroArchitecture.Silvermont or MicroArchitecture.Airmont => 1.0e-6f * (1 << (int)((eax >> 8) & 0x1F)),
_ => 1.0f / (1 << (int)((eax >> 8) & 0x1F))
};
}
if (EnergyUnitsMultiplier != 0)
{
string[] powerSensorLabels = { "CPU Package", "CPU Cores", "CPU Graphics", "CPU Memory", "CPU Platform" };
for (int i = 0; i < _energyStatusMsrs.Length; i++)
{
if (!Ring0.ReadMsr(_energyStatusMsrs[i], out eax, out uint _))
continue;
// Don't show the "GPU Graphics" sensor on windows, it will show up under the GPU instead.
if (i == 2 && !Software.OperatingSystem.IsUnix)
continue;
_lastEnergyTime[i] = DateTime.UtcNow;
_lastEnergyConsumed[i] = eax;
_powerSensors[i] = new Sensor(powerSensorLabels[i],
i,
SensorType.Power,
this,
settings);
ActivateSensor(_powerSensors[i]);
}
}
}
if (Ring0.ReadMsr(IA32_PERF_STATUS, out eax, out uint _) && ((eax >> 32) & 0xFFFF) > 0)
{
_coreVoltage = new Sensor("CPU Core", 0, SensorType.Voltage, this, settings);
ActivateSensor(_coreVoltage);
}
_coreVIDs = new Sensor[_coreCount];
for (int i = 0; i < _coreVIDs.Length; i++)
{
_coreVIDs[i] = new Sensor(CoreString(i), i + 1, SensorType.Voltage, this, settings);
ActivateSensor(_coreVIDs[i]);
}
Update();
}
public float EnergyUnitsMultiplier { get; }
private float[] Floats(float f)
{
float[] result = new float[_coreCount];
for (int i = 0; i < _coreCount; i++)
result[i] = f;
return result;
}
private float[] GetTjMaxFromMsr()
{
float[] result = new float[_coreCount];
for (int i = 0; i < _coreCount; i++)
{
if (Ring0.ReadMsr(IA32_TEMPERATURE_TARGET, out uint eax, out uint _, _cpuId[i][0].Affinity))
result[i] = (eax >> 16) & 0xFF;
else
result[i] = 100;
}
return result;
}
protected override uint[] GetMsrs()
{
return new[]
{
MSR_PLATFORM_INFO,
IA32_PERF_STATUS,
IA32_THERM_STATUS_MSR,
IA32_TEMPERATURE_TARGET,
IA32_PACKAGE_THERM_STATUS,
MSR_RAPL_POWER_UNIT,
MSR_PKG_ENERGY_STATUS,
MSR_DRAM_ENERGY_STATUS,
MSR_PP0_ENERGY_STATUS,
MSR_PP1_ENERGY_STATUS,
MSR_PLATFORM_ENERGY_STATUS,
};
}
public override string GetReport()
{
StringBuilder r = new();
r.Append(base.GetReport());
r.Append("MicroArchitecture: ");
r.AppendLine(_microArchitecture.ToString());
r.Append("Time Stamp Counter Multiplier: ");
r.AppendLine(_timeStampCounterMultiplier.ToString(CultureInfo.InvariantCulture));
r.AppendLine();
return r.ToString();
}
public override void Update()
{
base.Update();
float coreMax = float.MinValue;
float coreAvg = 0;
uint eax;
for (int i = 0; i < _coreTemperatures.Length; i++)
{
// if reading is valid
if (Ring0.ReadMsr(IA32_THERM_STATUS_MSR, out eax, out _, _cpuId[i][0].Affinity) && (eax & 0x80000000) != 0)
{
// get the dist from tjMax from bits 22:16
float deltaT = (eax & 0x007F0000) >> 16;
float tjMax = _coreTemperatures[i].Parameters[0].Value;
float tSlope = _coreTemperatures[i].Parameters[1].Value;
_coreTemperatures[i].Value = tjMax - (tSlope * deltaT);
coreAvg += (float)_coreTemperatures[i].Value;
if (coreMax < _coreTemperatures[i].Value)
coreMax = (float)_coreTemperatures[i].Value;
_distToTjMaxTemperatures[i].Value = deltaT;
}
else
{
_coreTemperatures[i].Value = null;
_distToTjMaxTemperatures[i].Value = null;
}
}
//calculate average cpu temperature over all cores
if (_coreMax != null && coreMax != float.MinValue)
{
_coreMax.Value = coreMax;
coreAvg /= _coreTemperatures.Length;
_coreAvg.Value = coreAvg;
}
if (_packageTemperature != null)
{
// if reading is valid
if (Ring0.ReadMsr(IA32_PACKAGE_THERM_STATUS, out eax, out _, _cpuId[0][0].Affinity) && (eax & 0x80000000) != 0)
{
// get the dist from tjMax from bits 22:16
float deltaT = (eax & 0x007F0000) >> 16;
float tjMax = _packageTemperature.Parameters[0].Value;
float tSlope = _packageTemperature.Parameters[1].Value;
_packageTemperature.Value = tjMax - (tSlope * deltaT);
}
else
{
_packageTemperature.Value = null;
}
}
if (HasTimeStampCounter && _timeStampCounterMultiplier > 0)
{
double newBusClock = 0;
for (int i = 0; i < _coreClocks.Length; i++)
{
System.Threading.Thread.Sleep(1);
if (Ring0.ReadMsr(IA32_PERF_STATUS, out eax, out _, _cpuId[i][0].Affinity))
{
newBusClock = TimeStampCounterFrequency / _timeStampCounterMultiplier;
switch (_microArchitecture)
{
case MicroArchitecture.Nehalem:
_coreClocks[i].Value = (float)((eax & 0xff) * newBusClock);
break;
case MicroArchitecture.Airmont:
case MicroArchitecture.AlderLake:
case MicroArchitecture.ArrowLake:
case MicroArchitecture.Broadwell:
case MicroArchitecture.CannonLake:
case MicroArchitecture.CometLake:
case MicroArchitecture.Goldmont:
case MicroArchitecture.GoldmontPlus:
case MicroArchitecture.Haswell:
case MicroArchitecture.IceLake:
case MicroArchitecture.IvyBridge:
case MicroArchitecture.JasperLake:
case MicroArchitecture.KabyLake:
case MicroArchitecture.LunarLake:
case MicroArchitecture.MeteorLake:
case MicroArchitecture.RaptorLake:
case MicroArchitecture.RocketLake:
case MicroArchitecture.SandyBridge:
case MicroArchitecture.Silvermont:
case MicroArchitecture.Skylake:
case MicroArchitecture.TigerLake:
case MicroArchitecture.Tremont:
_coreClocks[i].Value = (float)(((eax >> 8) & 0xff) * newBusClock);
break;
default:
_coreClocks[i].Value = (float)((((eax >> 8) & 0x1f) + (0.5 * ((eax >> 14) & 1))) * newBusClock);
break;
}
}
else
{
// if IA32_PERF_STATUS is not available, assume TSC frequency
_coreClocks[i].Value = (float)TimeStampCounterFrequency;
}
}
if (newBusClock > 0)
{
_busClock.Value = (float)newBusClock;
ActivateSensor(_busClock);
}
}
if (_powerSensors != null)
{
foreach (Sensor sensor in _powerSensors)
{
if (sensor == null)
continue;
if (!Ring0.ReadMsr(_energyStatusMsrs[sensor.Index], out eax, out _))
continue;
DateTime time = DateTime.UtcNow;
uint energyConsumed = eax;
float deltaTime = (float)(time - _lastEnergyTime[sensor.Index]).TotalSeconds;
if (deltaTime < 0.01)
continue;
sensor.Value = EnergyUnitsMultiplier * unchecked(energyConsumed - _lastEnergyConsumed[sensor.Index]) / deltaTime;
_lastEnergyTime[sensor.Index] = time;
_lastEnergyConsumed[sensor.Index] = energyConsumed;
}
}
if (_coreVoltage != null && Ring0.ReadMsr(IA32_PERF_STATUS, out _, out uint edx))
{
_coreVoltage.Value = ((edx >> 32) & 0xFFFF) / (float)(1 << 13);
}
for (int i = 0; i < _coreVIDs.Length; i++)
{
if (Ring0.ReadMsr(IA32_PERF_STATUS, out _, out edx, _cpuId[i][0].Affinity) && ((edx >> 32) & 0xFFFF) > 0)
{
_coreVIDs[i].Value = ((edx >> 32) & 0xFFFF) / (float)(1 << 13);
ActivateSensor(_coreVIDs[i]);
}
else
{
DeactivateSensor(_coreVIDs[i]);
}
}
}
[SuppressMessage("ReSharper", "IdentifierTypo")]
private enum MicroArchitecture
{
Airmont,
AlderLake,
Atom,
ArrowLake, // Gen. 15 (0xC6, -H = 0xC5)
Broadwell,
CannonLake,
CometLake,
Core,
Goldmont,
GoldmontPlus,
Haswell,
IceLake,
IvyBridge,
JasperLake,
KabyLake,
LunarLake,
Nehalem,
NetBurst,
MeteorLake,
RocketLake,
SandyBridge,
Silvermont,
Skylake,
TigerLake,
Tremont,
RaptorLake,
Unknown
}
// ReSharper disable InconsistentNaming
private const uint IA32_PACKAGE_THERM_STATUS = 0x1B1;
private const uint IA32_PERF_STATUS = 0x0198;
private const uint IA32_TEMPERATURE_TARGET = 0x01A2;
private const uint IA32_THERM_STATUS_MSR = 0x019C;
private const uint MSR_DRAM_ENERGY_STATUS = 0x619;
private const uint MSR_PKG_ENERGY_STATUS = 0x611;
private const uint MSR_PLATFORM_INFO = 0xCE;
private const uint MSR_PP0_ENERGY_STATUS = 0x639;
private const uint MSR_PP1_ENERGY_STATUS = 0x641;
private const uint MSR_PLATFORM_ENERGY_STATUS = 0x64D;
private const uint MSR_RAPL_POWER_UNIT = 0x606;
// ReSharper restore InconsistentNaming
}