mirror of
https://github.com/openhardwaremonitor/openhardwaremonitor
synced 2025-09-01 06:45:12 +00:00
Added core clock and bus speed support for Intel Core i5, i7 CPUs.
This commit is contained in:
@@ -48,6 +48,10 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
private string name;
|
private string name;
|
||||||
private Image icon;
|
private Image icon;
|
||||||
|
|
||||||
|
private uint family;
|
||||||
|
private uint model;
|
||||||
|
private uint stepping;
|
||||||
|
|
||||||
private Sensor[] coreTemperatures;
|
private Sensor[] coreTemperatures;
|
||||||
private Sensor totalLoad;
|
private Sensor totalLoad;
|
||||||
private Sensor[] coreLoads;
|
private Sensor[] coreLoads;
|
||||||
@@ -63,17 +67,23 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
|
|
||||||
private ulong lastCount;
|
private ulong lastCount;
|
||||||
private long lastTime;
|
private long lastTime;
|
||||||
|
private uint maxNehalemMultiplier = 0;
|
||||||
|
|
||||||
private const uint IA32_THERM_STATUS_MSR = 0x019C;
|
private const uint IA32_THERM_STATUS_MSR = 0x019C;
|
||||||
private const uint IA32_TEMPERATURE_TARGET = 0x01A2;
|
private const uint IA32_TEMPERATURE_TARGET = 0x01A2;
|
||||||
private const uint IA32_PERF_STATUS = 0x0198;
|
private const uint IA32_PERF_STATUS = 0x0198;
|
||||||
|
private const uint MSR_PLATFORM_INFO = 0xCE;
|
||||||
|
|
||||||
public IntelCPU(string name, uint family, uint model, uint stepping,
|
public IntelCPU(string name, uint family, uint model, uint stepping,
|
||||||
uint[,] cpuidData, uint[,] cpuidExtData) {
|
uint[,] cpuidData, uint[,] cpuidExtData) {
|
||||||
|
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.icon = Utilities.EmbeddedResources.GetImage("cpu.png");
|
this.icon = Utilities.EmbeddedResources.GetImage("cpu.png");
|
||||||
|
|
||||||
|
this.family = family;
|
||||||
|
this.model = model;
|
||||||
|
this.stepping = stepping;
|
||||||
|
|
||||||
logicalProcessors = 0;
|
logicalProcessors = 0;
|
||||||
if (cpuidData.GetLength(0) > 0x0B) {
|
if (cpuidData.GetLength(0) > 0x0B) {
|
||||||
uint eax, ebx, ecx, edx;
|
uint eax, ebx, ecx, edx;
|
||||||
@@ -124,10 +134,11 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
tjMax = 100; break;
|
tjMax = 100; break;
|
||||||
case 0x1C: // Intel Atom
|
case 0x1C: // Intel Atom
|
||||||
tjMax = 90; break;
|
tjMax = 90; break;
|
||||||
case 0x1A:
|
case 0x1A: // Intel Core i7
|
||||||
uint eax = 0, edx = 0;
|
case 0x1E: // Intel Core i5
|
||||||
if (WinRing0.RdmsrPx(
|
uint eax, edx;
|
||||||
IA32_TEMPERATURE_TARGET, ref eax, ref edx, (UIntPtr)1)) {
|
if (WinRing0.Rdmsr(IA32_TEMPERATURE_TARGET, out eax, out edx))
|
||||||
|
{
|
||||||
tjMax = (eax >> 16) & 0xFF;
|
tjMax = (eax >> 16) & 0xFF;
|
||||||
} else
|
} else
|
||||||
tjMax = 100;
|
tjMax = 100;
|
||||||
@@ -139,6 +150,13 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
default: tjMax = 100; break;
|
default: tjMax = 100; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (family == 0x06 && model >= 0x1A) { // Core i5, i7
|
||||||
|
uint eax, edx;
|
||||||
|
if (WinRing0.Rdmsr(MSR_PLATFORM_INFO, out eax, out edx)) {
|
||||||
|
maxNehalemMultiplier = (eax >> 8) & 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
coreTemperatures = new Sensor[coreCount];
|
coreTemperatures = new Sensor[coreCount];
|
||||||
for (int i = 0; i < coreTemperatures.Length; i++) {
|
for (int i = 0; i < coreTemperatures.Length; i++) {
|
||||||
coreTemperatures[i] = new Sensor("Core #" + (i + 1), i, tjMax,
|
coreTemperatures[i] = new Sensor("Core #" + (i + 1), i, tjMax,
|
||||||
@@ -204,9 +222,9 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
public void Update() {
|
public void Update() {
|
||||||
|
|
||||||
for (int i = 0; i < coreTemperatures.Length; i++) {
|
for (int i = 0; i < coreTemperatures.Length; i++) {
|
||||||
uint eax = 0, edx = 0;
|
uint eax, edx;
|
||||||
if (WinRing0.RdmsrPx(
|
if (WinRing0.RdmsrTx(
|
||||||
IA32_THERM_STATUS_MSR, ref eax, ref edx,
|
IA32_THERM_STATUS_MSR, out eax, out edx,
|
||||||
(UIntPtr)(1 << (int)(logicalProcessorsPerCore * i))))
|
(UIntPtr)(1 << (int)(logicalProcessorsPerCore * i))))
|
||||||
{
|
{
|
||||||
// if reading is valid
|
// if reading is valid
|
||||||
@@ -227,33 +245,41 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
totalLoad.Value = cpuLoad.GetTotalLoad();
|
totalLoad.Value = cpuLoad.GetTotalLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint lsb = 0, msb = 0;
|
uint lsb, msb;
|
||||||
bool valid = WinRing0.RdtscPx(ref lsb, ref msb, (UIntPtr)1);
|
bool valid = WinRing0.RdtscTx(out lsb, out msb, (UIntPtr)1);
|
||||||
long time = Stopwatch.GetTimestamp();
|
long time = Stopwatch.GetTimestamp();
|
||||||
ulong count = ((ulong)msb << 32) | lsb;
|
ulong count = ((ulong)msb << 32) | lsb;
|
||||||
double delta = ((double)(time - lastTime)) / Stopwatch.Frequency;
|
double delta = ((double)(time - lastTime)) / Stopwatch.Frequency;
|
||||||
if (valid && delta > 0.5) {
|
if (valid && delta > 0.5) {
|
||||||
double maxClock = (float)((count - lastCount) / (1e6 * delta));
|
double maxClock = (count - lastCount) / (1e6 * delta);
|
||||||
double busClock = 0;
|
double busClock = 0;
|
||||||
uint eax, edx;
|
uint eax, edx;
|
||||||
for (int i = 0; i < coreClocks.Length; i++) {
|
for (int i = 0; i < coreClocks.Length; i++) {
|
||||||
eax = 0; edx = 0;
|
|
||||||
System.Threading.Thread.Sleep(1);
|
System.Threading.Thread.Sleep(1);
|
||||||
if (WinRing0.RdmsrPx(IA32_PERF_STATUS, ref eax, ref edx,
|
if (WinRing0.RdmsrTx(IA32_PERF_STATUS, out eax, out edx,
|
||||||
(UIntPtr)(1 << (int)(logicalProcessorsPerCore * i)))) {
|
(UIntPtr)(1 << (int)(logicalProcessorsPerCore * i)))) {
|
||||||
uint multiplier = (eax >> 8) & 0x1f;
|
if (model < 0x1A) { // Core 2
|
||||||
uint maxMultiplier = (edx >> 8) & 0x1f;
|
uint multiplier = (eax >> 8) & 0x1f;
|
||||||
// factor = multiplier * 2 to handle non integer multipliers
|
uint maxMultiplier = (edx >> 8) & 0x1f;
|
||||||
uint factor = (multiplier << 1) | ((eax >> 14) & 1);
|
// factor = multiplier * 2 to handle non integer multipliers
|
||||||
uint maxFactor = (maxMultiplier << 1) | ((edx >> 14) & 1);
|
uint factor = (multiplier << 1) | ((eax >> 14) & 1);
|
||||||
if (maxFactor > 0) {
|
uint maxFactor = (maxMultiplier << 1) | ((edx >> 14) & 1);
|
||||||
coreClocks[i].Value = (float)(factor * maxClock / maxFactor);
|
if (maxFactor > 0) {
|
||||||
busClock = (float)(2 * maxClock / maxFactor);
|
coreClocks[i].Value = (float)(factor * maxClock / maxFactor);
|
||||||
|
busClock = (float)(2 * maxClock / maxFactor);
|
||||||
|
}
|
||||||
|
} else { // Core i5, i7
|
||||||
|
uint nehalemMultiplier = eax & 0xff;
|
||||||
|
if (maxNehalemMultiplier > 0) {
|
||||||
|
coreClocks[i].Value =
|
||||||
|
(float)(nehalemMultiplier * maxClock / maxNehalemMultiplier);
|
||||||
|
busClock = (float)(maxClock / maxNehalemMultiplier);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else { // Intel Pentium 4
|
||||||
// if IA32_PERF_STATUS is not available, assume maxClock
|
// if IA32_PERF_STATUS is not available, assume maxClock
|
||||||
coreClocks[i].Value = (float)maxClock;
|
coreClocks[i].Value = (float)maxClock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (busClock > 0) {
|
if (busClock > 0) {
|
||||||
this.busClock.Value = (float)busClock;
|
this.busClock.Value = (float)busClock;
|
||||||
@@ -262,6 +288,6 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
}
|
}
|
||||||
lastCount = count;
|
lastCount = count;
|
||||||
lastTime = time;
|
lastTime = time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -83,8 +83,9 @@ namespace OpenHardwareMonitor.Hardware {
|
|||||||
out uint eax, out uint ebx, out uint ecx, out uint edx);
|
out uint eax, out uint ebx, out uint ecx, out uint edx);
|
||||||
public delegate bool CpuidExDelegate(uint index, uint ecxValue,
|
public delegate bool CpuidExDelegate(uint index, uint ecxValue,
|
||||||
out uint eax, out uint ebx, out uint ecx, out uint edx);
|
out uint eax, out uint ebx, out uint ecx, out uint edx);
|
||||||
public delegate bool RdmsrPxDelegate(uint index, ref uint eax, ref uint edx,
|
public delegate bool RdmsrDelegate(uint index, out uint eax, out uint edx);
|
||||||
UIntPtr processAffinityMask);
|
public delegate bool RdmsrTxDelegate(uint index, out uint eax, out uint edx,
|
||||||
|
UIntPtr threadAffinityMask);
|
||||||
public delegate byte ReadIoPortByteDelegate(ushort port);
|
public delegate byte ReadIoPortByteDelegate(ushort port);
|
||||||
public delegate void WriteIoPortByteDelegate(ushort port, byte value);
|
public delegate void WriteIoPortByteDelegate(ushort port, byte value);
|
||||||
public delegate void SetPciMaxBusIndexDelegate(byte max);
|
public delegate void SetPciMaxBusIndexDelegate(byte max);
|
||||||
@@ -94,8 +95,8 @@ namespace OpenHardwareMonitor.Hardware {
|
|||||||
uint regAddress, out uint value);
|
uint regAddress, out uint value);
|
||||||
public delegate bool WritePciConfigDwordExDelegate(uint pciAddress,
|
public delegate bool WritePciConfigDwordExDelegate(uint pciAddress,
|
||||||
uint regAddress, uint value);
|
uint regAddress, uint value);
|
||||||
public delegate bool RdtscPxDelegate(ref uint eax, ref uint edx,
|
public delegate bool RdtscTxDelegate(out uint eax, out uint edx,
|
||||||
UIntPtr processAffinityMask);
|
UIntPtr threadAffinityMask);
|
||||||
|
|
||||||
private static InitializeOlsDelegate InitializeOls;
|
private static InitializeOlsDelegate InitializeOls;
|
||||||
private static DeinitializeOlsDelegate DeinitializeOls;
|
private static DeinitializeOlsDelegate DeinitializeOls;
|
||||||
@@ -104,14 +105,15 @@ namespace OpenHardwareMonitor.Hardware {
|
|||||||
public static IsCpuidDelegate IsCpuid;
|
public static IsCpuidDelegate IsCpuid;
|
||||||
public static CpuidDelegate Cpuid;
|
public static CpuidDelegate Cpuid;
|
||||||
public static CpuidExDelegate CpuidEx;
|
public static CpuidExDelegate CpuidEx;
|
||||||
public static RdmsrPxDelegate RdmsrPx;
|
public static RdmsrDelegate Rdmsr;
|
||||||
|
public static RdmsrTxDelegate RdmsrTx;
|
||||||
public static ReadIoPortByteDelegate ReadIoPortByte;
|
public static ReadIoPortByteDelegate ReadIoPortByte;
|
||||||
public static WriteIoPortByteDelegate WriteIoPortByte;
|
public static WriteIoPortByteDelegate WriteIoPortByte;
|
||||||
public static SetPciMaxBusIndexDelegate SetPciMaxBusIndex;
|
public static SetPciMaxBusIndexDelegate SetPciMaxBusIndex;
|
||||||
public static FindPciDeviceByIdDelegate FindPciDeviceById;
|
public static FindPciDeviceByIdDelegate FindPciDeviceById;
|
||||||
public static ReadPciConfigDwordExDelegate ReadPciConfigDwordEx;
|
public static ReadPciConfigDwordExDelegate ReadPciConfigDwordEx;
|
||||||
public static WritePciConfigDwordExDelegate WritePciConfigDwordEx;
|
public static WritePciConfigDwordExDelegate WritePciConfigDwordEx;
|
||||||
public static RdtscPxDelegate RdtscPx;
|
public static RdtscTxDelegate RdtscTx;
|
||||||
|
|
||||||
private static void GetDelegate<T>(string entryPoint, out T newDelegate)
|
private static void GetDelegate<T>(string entryPoint, out T newDelegate)
|
||||||
where T : class
|
where T : class
|
||||||
@@ -131,14 +133,15 @@ namespace OpenHardwareMonitor.Hardware {
|
|||||||
GetDelegate("IsCpuid", out IsCpuid);
|
GetDelegate("IsCpuid", out IsCpuid);
|
||||||
GetDelegate("Cpuid", out Cpuid);
|
GetDelegate("Cpuid", out Cpuid);
|
||||||
GetDelegate("CpuidEx", out CpuidEx);
|
GetDelegate("CpuidEx", out CpuidEx);
|
||||||
GetDelegate("RdmsrPx", out RdmsrPx);
|
GetDelegate("Rdmsr", out Rdmsr);
|
||||||
|
GetDelegate("RdmsrTx", out RdmsrTx);
|
||||||
GetDelegate("ReadIoPortByte", out ReadIoPortByte);
|
GetDelegate("ReadIoPortByte", out ReadIoPortByte);
|
||||||
GetDelegate("WriteIoPortByte", out WriteIoPortByte);
|
GetDelegate("WriteIoPortByte", out WriteIoPortByte);
|
||||||
GetDelegate("SetPciMaxBusIndex", out SetPciMaxBusIndex);
|
GetDelegate("SetPciMaxBusIndex", out SetPciMaxBusIndex);
|
||||||
GetDelegate("FindPciDeviceById", out FindPciDeviceById);
|
GetDelegate("FindPciDeviceById", out FindPciDeviceById);
|
||||||
GetDelegate("ReadPciConfigDwordEx", out ReadPciConfigDwordEx);
|
GetDelegate("ReadPciConfigDwordEx", out ReadPciConfigDwordEx);
|
||||||
GetDelegate("WritePciConfigDwordEx", out WritePciConfigDwordEx);
|
GetDelegate("WritePciConfigDwordEx", out WritePciConfigDwordEx);
|
||||||
GetDelegate("RdtscPx", out RdtscPx);
|
GetDelegate("RdtscTx", out RdtscTx);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (InitializeOls != null && InitializeOls())
|
if (InitializeOls != null && InitializeOls())
|
||||||
|
@@ -69,5 +69,5 @@ using System.Runtime.InteropServices;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("0.1.20.1")]
|
[assembly: AssemblyVersion("0.1.21.0")]
|
||||||
[assembly: AssemblyFileVersion("0.1.20.1")]
|
[assembly: AssemblyFileVersion("0.1.21.0")]
|
||||||
|
Reference in New Issue
Block a user