mirror of
https://github.com/openhardwaremonitor/openhardwaremonitor
synced 2025-09-01 14:55:13 +00:00
Implemented APIC based CPU enumeration (Issue 41).
This commit is contained in:
BIN
External/WinRing0.dll
vendored
BIN
External/WinRing0.dll
vendored
Binary file not shown.
BIN
External/WinRing0x64.dll
vendored
BIN
External/WinRing0x64.dll
vendored
Binary file not shown.
@@ -63,41 +63,46 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
private const byte THERM_SENSE_CORE_SEL_CPU0 = 0x4;
|
private const byte THERM_SENSE_CORE_SEL_CPU0 = 0x4;
|
||||||
private const byte THERM_SENSE_CORE_SEL_CPU1 = 0x0;
|
private const byte THERM_SENSE_CORE_SEL_CPU1 = 0x0;
|
||||||
|
|
||||||
public AMD0FCPU(string name, uint family, uint model, uint stepping,
|
public AMD0FCPU(CPUID[][] cpuid) {
|
||||||
uint[,] cpuidData, uint[,] cpuidExtData) {
|
|
||||||
|
|
||||||
this.name = name;
|
this.name = cpuid[0][0].Name;
|
||||||
this.icon = Utilities.EmbeddedResources.GetImage("cpu.png");
|
this.icon = Utilities.EmbeddedResources.GetImage("cpu.png");
|
||||||
|
|
||||||
uint coreCount = 1;
|
int coreCount = cpuid.Length;
|
||||||
if (cpuidExtData.GetLength(0) > 8)
|
|
||||||
coreCount = (cpuidExtData[8, 2] & 0xFF) + 1;
|
|
||||||
|
|
||||||
// max two cores
|
|
||||||
coreCount = coreCount > 2 ? 2 : coreCount;
|
|
||||||
|
|
||||||
totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this);
|
totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this);
|
||||||
|
|
||||||
float offset = -49.0f;
|
float offset = -49.0f;
|
||||||
|
|
||||||
// AM2+ 65nm +21 offset
|
// AM2+ 65nm +21 offset
|
||||||
|
uint model = cpuid[0][0].Model;
|
||||||
if (model >= 0x69 && model != 0xc1 && model != 0x6c && model != 0x7c)
|
if (model >= 0x69 && model != 0xc1 && model != 0x6c && model != 0x7c)
|
||||||
offset += 21;
|
offset += 21;
|
||||||
|
|
||||||
coreTemperatures = new Sensor[coreCount];
|
// check if processor supports a digital thermal sensor
|
||||||
coreLoads = new Sensor[coreCount];
|
if (cpuid[0][0].ExtData.GetLength(0) > 7 &&
|
||||||
for (int i = 0; i < coreCount; i++) {
|
(cpuid[0][0].ExtData[7, 3] & 1) != 0)
|
||||||
coreTemperatures[i] =
|
{
|
||||||
new Sensor("Core #" + (i + 1), i, null, SensorType.Temperature, this,
|
coreTemperatures = new Sensor[coreCount];
|
||||||
new ParameterDescription[] { new ParameterDescription("Offset",
|
for (int i = 0; i < coreCount; i++) {
|
||||||
"Temperature offset of the thermal sensor.\n" +
|
coreTemperatures[i] =
|
||||||
"Temperature = Value + Offset.", offset)
|
new Sensor("Core #" + (i + 1), i, null, SensorType.Temperature,
|
||||||
|
this, new ParameterDescription[] {
|
||||||
|
new ParameterDescription("Offset",
|
||||||
|
"Temperature offset of the thermal sensor.\n" +
|
||||||
|
"Temperature = Value + Offset.", offset)
|
||||||
});
|
});
|
||||||
coreLoads[i] = new Sensor("Core #" + (i + 1), i + 1,
|
}
|
||||||
SensorType.Load, this);
|
} else {
|
||||||
|
coreTemperatures = new Sensor[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
cpuLoad = new CPULoad(coreCount, 1);
|
coreLoads = new Sensor[coreCount];
|
||||||
|
for (int i = 0; i < coreCount; i++)
|
||||||
|
coreLoads[i] = new Sensor("Core #" + (i + 1), i + 1,
|
||||||
|
SensorType.Load, this);
|
||||||
|
|
||||||
|
cpuLoad = new CPULoad(cpuid);
|
||||||
if (cpuLoad.IsAvailable) {
|
if (cpuLoad.IsAvailable) {
|
||||||
foreach (Sensor sensor in coreLoads)
|
foreach (Sensor sensor in coreLoads)
|
||||||
ActivateSensor(sensor);
|
ActivateSensor(sensor);
|
||||||
@@ -128,7 +133,6 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
|
|
||||||
public void Update() {
|
public void Update() {
|
||||||
if (pciAddress != 0xFFFFFFFF) {
|
if (pciAddress != 0xFFFFFFFF) {
|
||||||
|
|
||||||
for (uint i = 0; i < coreTemperatures.Length; i++) {
|
for (uint i = 0; i < coreTemperatures.Length; i++) {
|
||||||
if (WinRing0.WritePciConfigDwordEx(
|
if (WinRing0.WritePciConfigDwordEx(
|
||||||
pciAddress, THERMTRIP_STATUS_REGISTER,
|
pciAddress, THERMTRIP_STATUS_REGISTER,
|
||||||
|
@@ -60,15 +60,12 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
private const ushort PCI_AMD_11H_MISCELLANEOUS_DEVICE_ID = 0x1303;
|
private const ushort PCI_AMD_11H_MISCELLANEOUS_DEVICE_ID = 0x1303;
|
||||||
private const uint REPORTED_TEMPERATURE_CONTROL_REGISTER = 0xA4;
|
private const uint REPORTED_TEMPERATURE_CONTROL_REGISTER = 0xA4;
|
||||||
|
|
||||||
public AMD10CPU(string name, uint family, uint model, uint stepping,
|
public AMD10CPU(CPUID[][] cpuid) {
|
||||||
uint[,] cpuidData, uint[,] cpuidExtData) {
|
|
||||||
|
|
||||||
this.name = name;
|
this.name = cpuid[0][0].Name;
|
||||||
this.icon = Utilities.EmbeddedResources.GetImage("cpu.png");
|
this.icon = Utilities.EmbeddedResources.GetImage("cpu.png");
|
||||||
|
|
||||||
uint coreCount = 1;
|
int coreCount = cpuid.Length;
|
||||||
if (cpuidExtData.GetLength(0) > 8)
|
|
||||||
coreCount = (cpuidExtData[8, 2] & 0xFF) + 1;
|
|
||||||
|
|
||||||
totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this);
|
totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this);
|
||||||
|
|
||||||
@@ -77,7 +74,7 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
coreLoads[i] = new Sensor("Core #" + (i + 1), i + 1,
|
coreLoads[i] = new Sensor("Core #" + (i + 1), i + 1,
|
||||||
SensorType.Load, this);
|
SensorType.Load, this);
|
||||||
|
|
||||||
cpuLoad = new CPULoad(coreCount, 1);
|
cpuLoad = new CPULoad(cpuid);
|
||||||
if (cpuLoad.IsAvailable) {
|
if (cpuLoad.IsAvailable) {
|
||||||
foreach (Sensor sensor in coreLoads)
|
foreach (Sensor sensor in coreLoads)
|
||||||
ActivateSensor(sensor);
|
ActivateSensor(sensor);
|
||||||
|
@@ -37,6 +37,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace OpenHardwareMonitor.Hardware.CPU {
|
namespace OpenHardwareMonitor.Hardware.CPU {
|
||||||
@@ -44,113 +45,93 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
public class CPUGroup : IGroup {
|
public class CPUGroup : IGroup {
|
||||||
private List<IHardware> hardware = new List<IHardware>();
|
private List<IHardware> hardware = new List<IHardware>();
|
||||||
|
|
||||||
private string cpuBrandString;
|
private CPUID[][][] threads;
|
||||||
private string cpuVendor;
|
|
||||||
private uint[,] cpuidData;
|
|
||||||
private uint[,] cpuidExtData;
|
|
||||||
|
|
||||||
private uint family;
|
private CPUID[][] GetProcessorThreads() {
|
||||||
private uint model;
|
|
||||||
private uint stepping;
|
|
||||||
|
|
||||||
private static uint CPUID = 0;
|
List<CPUID> threads = new List<CPUID>();
|
||||||
private static uint CPUID_EXT = 0x80000000;
|
for (int i = 0; i < 32; i++) {
|
||||||
|
try {
|
||||||
|
threads.Add(new CPUID(i));
|
||||||
|
} catch (ArgumentException) { }
|
||||||
|
}
|
||||||
|
|
||||||
public static void AppendRegister(StringBuilder b, uint value) {
|
SortedDictionary<uint, List<CPUID>> processors =
|
||||||
b.Append((char)((value) & 0xff));
|
new SortedDictionary<uint, List<CPUID>>();
|
||||||
b.Append((char)((value >> 8) & 0xff));
|
foreach (CPUID thread in threads) {
|
||||||
b.Append((char)((value >> 16) & 0xff));
|
List<CPUID> list;
|
||||||
b.Append((char)((value >> 24) & 0xff));
|
processors.TryGetValue(thread.ProcessorId, out list);
|
||||||
|
if (list == null) {
|
||||||
|
list = new List<CPUID>();
|
||||||
|
processors.Add(thread.ProcessorId, list);
|
||||||
|
}
|
||||||
|
list.Add(thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
CPUID[][] processorThreads = new CPUID[processors.Count][];
|
||||||
|
int index = 0;
|
||||||
|
foreach (List<CPUID> list in processors.Values) {
|
||||||
|
processorThreads[index] = list.ToArray();
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
return processorThreads;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CPUID[][] GroupThreadsByCore(CPUID[] threads) {
|
||||||
|
|
||||||
|
SortedDictionary<uint, List<CPUID>> cores =
|
||||||
|
new SortedDictionary<uint, List<CPUID>>();
|
||||||
|
foreach (CPUID thread in threads) {
|
||||||
|
List<CPUID> coreList;
|
||||||
|
cores.TryGetValue(thread.CoreId, out coreList);
|
||||||
|
if (coreList == null) {
|
||||||
|
coreList = new List<CPUID>();
|
||||||
|
cores.Add(thread.CoreId, coreList);
|
||||||
|
}
|
||||||
|
coreList.Add(thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
CPUID[][] coreThreads = new CPUID[cores.Count][];
|
||||||
|
int index = 0;
|
||||||
|
foreach (List<CPUID> list in cores.Values) {
|
||||||
|
coreThreads[index] = list.ToArray();
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
return coreThreads;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CPUGroup() {
|
public CPUGroup() {
|
||||||
|
if (!WinRing0.IsCpuid())
|
||||||
if (!WinRing0.IsAvailable)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (WinRing0.IsCpuid()) {
|
CPUID[][] processorThreads = GetProcessorThreads();
|
||||||
uint maxCPUID = 0;
|
this.threads = new CPUID[processorThreads.Length][][];
|
||||||
uint maxCPUID_EXT = 0;
|
|
||||||
uint eax, ebx, ecx, edx;
|
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
foreach (CPUID[] threads in processorThreads) {
|
||||||
|
if (threads.Length == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (WinRing0.Cpuid(CPUID, out eax, out ebx, out ecx, out edx)) {
|
CPUID[][] coreThreads = GroupThreadsByCore(threads);
|
||||||
maxCPUID = eax;
|
|
||||||
StringBuilder vendorBuilder = new StringBuilder();
|
|
||||||
AppendRegister(vendorBuilder, ebx);
|
|
||||||
AppendRegister(vendorBuilder, edx);
|
|
||||||
AppendRegister(vendorBuilder, ecx);
|
|
||||||
cpuVendor = vendorBuilder.ToString();
|
|
||||||
|
|
||||||
eax = ebx = ecx = edx = 0;
|
this.threads[index] = coreThreads;
|
||||||
if (WinRing0.Cpuid(CPUID_EXT, out eax, out ebx, out ecx, out edx)) {
|
index++;
|
||||||
maxCPUID_EXT = eax - CPUID_EXT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (maxCPUID == 0 || maxCPUID_EXT == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
cpuidData = new uint[maxCPUID + 1, 4];
|
switch (threads[0].Vendor) {
|
||||||
for (uint i = 0; i < (maxCPUID + 1); i++)
|
case Vendor.Intel:
|
||||||
WinRing0.Cpuid(CPUID + i, out cpuidData[i, 0], out cpuidData[i, 1],
|
hardware.Add(new IntelCPU(coreThreads));
|
||||||
out cpuidData[i, 2], out cpuidData[i, 3]);
|
|
||||||
|
|
||||||
cpuidExtData = new uint[maxCPUID_EXT + 1, 4];
|
|
||||||
for (uint i = 0; i < (maxCPUID_EXT + 1); i++)
|
|
||||||
WinRing0.Cpuid(CPUID_EXT + i, out cpuidExtData[i, 0],
|
|
||||||
out cpuidExtData[i, 1], out cpuidExtData[i, 2],
|
|
||||||
out cpuidExtData[i, 3]);
|
|
||||||
|
|
||||||
StringBuilder nameBuilder = new StringBuilder();
|
|
||||||
for (uint i = 2; i <= 4; i++) {
|
|
||||||
if (WinRing0.Cpuid(CPUID_EXT + i, out eax, out ebx, out ecx, out edx))
|
|
||||||
{
|
|
||||||
AppendRegister(nameBuilder, eax);
|
|
||||||
AppendRegister(nameBuilder, ebx);
|
|
||||||
AppendRegister(nameBuilder, ecx);
|
|
||||||
AppendRegister(nameBuilder, edx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nameBuilder.Replace('\0', ' ');
|
|
||||||
cpuBrandString = nameBuilder.ToString().Trim();
|
|
||||||
nameBuilder.Replace("(R)", " ");
|
|
||||||
nameBuilder.Replace("(TM)", " ");
|
|
||||||
nameBuilder.Replace("(tm)", " ");
|
|
||||||
nameBuilder.Replace("CPU", "");
|
|
||||||
for (int i = 0; i < 10; i++) nameBuilder.Replace(" ", " ");
|
|
||||||
string name = nameBuilder.ToString();
|
|
||||||
if (name.Contains("@"))
|
|
||||||
name = name.Remove(name.LastIndexOf('@'));
|
|
||||||
name = name.Trim();
|
|
||||||
|
|
||||||
this.family = ((cpuidData[1, 0] & 0x0FF00000) >> 20) +
|
|
||||||
((cpuidData[1, 0] & 0x0F00) >> 8);
|
|
||||||
this.model = ((cpuidData[1, 0] & 0x0F0000) >> 12) +
|
|
||||||
((cpuidData[1, 0] & 0xF0) >> 4);
|
|
||||||
this.stepping = (cpuidData[1, 0] & 0x0F);
|
|
||||||
|
|
||||||
switch (cpuVendor) {
|
|
||||||
case "GenuineIntel":
|
|
||||||
hardware.Add(new IntelCPU(name, family, model, stepping,
|
|
||||||
cpuidData, cpuidExtData));
|
|
||||||
break;
|
|
||||||
case "AuthenticAMD":
|
|
||||||
// check if processor supports a digital thermal sensor
|
|
||||||
if (maxCPUID_EXT >= 7 && (cpuidExtData[7, 3] & 1) != 0) {
|
|
||||||
switch (family) {
|
|
||||||
case 0x0F:
|
|
||||||
hardware.Add(new AMD0FCPU(name, family, model, stepping,
|
|
||||||
cpuidData, cpuidExtData));
|
|
||||||
break;
|
|
||||||
case 0x10:
|
|
||||||
hardware.Add(new AMD10CPU(name, family, model, stepping,
|
|
||||||
cpuidData, cpuidExtData));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
case Vendor.AMD:
|
||||||
|
switch (threads[0].Family) {
|
||||||
|
case 0x0F:
|
||||||
|
hardware.Add(new AMD0FCPU(coreThreads));
|
||||||
|
break;
|
||||||
|
case 0x10:
|
||||||
|
hardware.Add(new AMD10CPU(coreThreads));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
} break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -181,28 +162,39 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
|
|
||||||
r.AppendLine("CPUID");
|
r.AppendLine("CPUID");
|
||||||
r.AppendLine();
|
r.AppendLine();
|
||||||
r.AppendFormat("Processor Vendor: {0}{1}", cpuVendor,
|
|
||||||
Environment.NewLine);
|
|
||||||
r.AppendFormat("Processor Brand: {0}{1}", cpuBrandString,
|
|
||||||
Environment.NewLine);
|
|
||||||
r.AppendFormat("Family: 0x{0}{1}", family.ToString("X"),
|
|
||||||
Environment.NewLine);
|
|
||||||
r.AppendFormat("Model: 0x{0}{1}", model.ToString("X"),
|
|
||||||
Environment.NewLine);
|
|
||||||
r.AppendFormat("Stepping: 0x{0}{1}", stepping.ToString("X"),
|
|
||||||
Environment.NewLine);
|
|
||||||
r.AppendLine();
|
|
||||||
|
|
||||||
r.AppendLine("CPUID Return Values");
|
for (int i = 0; i < threads.Length; i++) {
|
||||||
r.AppendLine();
|
|
||||||
|
|
||||||
if (cpuidData != null) {
|
r.AppendLine("Processor " + i);
|
||||||
r.AppendLine(" Function EAX EBX ECX EDX");
|
r.AppendLine();
|
||||||
AppendCpuidData(r, cpuidData, CPUID);
|
r.AppendFormat("Processor Vendor: {0}{1}", threads[i][0][0].Vendor,
|
||||||
AppendCpuidData(r, cpuidExtData, CPUID_EXT);
|
Environment.NewLine);
|
||||||
|
r.AppendFormat("Processor Brand: {0}{1}", threads[i][0][0].BrandString,
|
||||||
|
Environment.NewLine);
|
||||||
|
r.AppendFormat("Family: 0x{0}{1}",
|
||||||
|
threads[i][0][0].Family.ToString("X"), Environment.NewLine);
|
||||||
|
r.AppendFormat("Model: 0x{0}{1}",
|
||||||
|
threads[i][0][0].Model.ToString("X"), Environment.NewLine);
|
||||||
|
r.AppendFormat("Stepping: 0x{0}{1}",
|
||||||
|
threads[i][0][0].Stepping.ToString("X"), Environment.NewLine);
|
||||||
r.AppendLine();
|
r.AppendLine();
|
||||||
}
|
|
||||||
|
|
||||||
|
r.AppendLine("CPUID Return Values");
|
||||||
|
r.AppendLine();
|
||||||
|
for (int j = 0; j < threads[i].Length; j++)
|
||||||
|
for (int k = 0; k < threads[i][j].Length; k++) {
|
||||||
|
r.AppendLine(" CPU Thread: " + threads[i][j][k].Thread);
|
||||||
|
r.AppendLine(" APIC ID: " + threads[i][j][k].ApicId);
|
||||||
|
r.AppendLine(" Processor ID: " + threads[i][j][k].ProcessorId);
|
||||||
|
r.AppendLine(" Core ID: " + threads[i][j][k].CoreId);
|
||||||
|
r.AppendLine(" Thread ID: " + threads[i][j][k].ThreadId);
|
||||||
|
r.AppendLine();
|
||||||
|
r.AppendLine(" Function EAX EBX ECX EDX");
|
||||||
|
AppendCpuidData(r, threads[i][j][k].Data, CPUID.CPUID_0);
|
||||||
|
AppendCpuidData(r, threads[i][j][k].ExtData, CPUID.CPUID_EXT);
|
||||||
|
r.AppendLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
return r.ToString();
|
return r.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
252
Hardware/CPU/CPUID.cs
Normal file
252
Hardware/CPU/CPUID.cs
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
|
||||||
|
The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.mozilla.org/MPL/
|
||||||
|
|
||||||
|
Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
for the specific language governing rights and limitations under the License.
|
||||||
|
|
||||||
|
The Original Code is the Open Hardware Monitor code.
|
||||||
|
|
||||||
|
The Initial Developer of the Original Code is
|
||||||
|
Michael Möller <m.moeller@gmx.ch>.
|
||||||
|
Portions created by the Initial Developer are Copyright (C) 2009-2010
|
||||||
|
the Initial Developer. All Rights Reserved.
|
||||||
|
|
||||||
|
Contributor(s):
|
||||||
|
|
||||||
|
Alternatively, the contents of this file may be used under the terms of
|
||||||
|
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
of those above. If you wish to allow use of your version of this file only
|
||||||
|
under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
use your version of this file under the terms of the MPL, indicate your
|
||||||
|
decision by deleting the provisions above and replace them with the notice
|
||||||
|
and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
the provisions above, a recipient may use your version of this file under
|
||||||
|
the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace OpenHardwareMonitor.Hardware.CPU {
|
||||||
|
|
||||||
|
public enum Vendor {
|
||||||
|
Unknown,
|
||||||
|
Intel,
|
||||||
|
AMD,
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CPUID {
|
||||||
|
|
||||||
|
private int thread;
|
||||||
|
|
||||||
|
private uint maxCpuid = 0;
|
||||||
|
private uint maxCpuidExt = 0;
|
||||||
|
|
||||||
|
private Vendor vendor;
|
||||||
|
|
||||||
|
private string cpuBrandString;
|
||||||
|
private string name;
|
||||||
|
|
||||||
|
private uint[,] cpuidData;
|
||||||
|
private uint[,] cpuidExtData;
|
||||||
|
|
||||||
|
private uint family;
|
||||||
|
private uint model;
|
||||||
|
private uint stepping;
|
||||||
|
|
||||||
|
private uint apicId;
|
||||||
|
|
||||||
|
private uint threadMaskWith;
|
||||||
|
private uint coreMaskWith;
|
||||||
|
|
||||||
|
private uint processorId;
|
||||||
|
private uint coreId;
|
||||||
|
private uint threadId;
|
||||||
|
|
||||||
|
public static uint CPUID_0 = 0;
|
||||||
|
public static uint CPUID_EXT = 0x80000000;
|
||||||
|
|
||||||
|
private void AppendRegister(StringBuilder b, uint value) {
|
||||||
|
b.Append((char)((value) & 0xff));
|
||||||
|
b.Append((char)((value >> 8) & 0xff));
|
||||||
|
b.Append((char)((value >> 16) & 0xff));
|
||||||
|
b.Append((char)((value >> 24) & 0xff));
|
||||||
|
}
|
||||||
|
|
||||||
|
public CPUID(int thread) {
|
||||||
|
this.thread = thread;
|
||||||
|
|
||||||
|
uint eax, ebx, ecx, edx;
|
||||||
|
|
||||||
|
UIntPtr mask = (UIntPtr)(1L << thread);
|
||||||
|
|
||||||
|
if (WinRing0.CpuidTx(CPUID_0, 0,
|
||||||
|
out eax, out ebx, out ecx, out edx, mask)) {
|
||||||
|
maxCpuid = eax;
|
||||||
|
StringBuilder vendorBuilder = new StringBuilder();
|
||||||
|
AppendRegister(vendorBuilder, ebx);
|
||||||
|
AppendRegister(vendorBuilder, edx);
|
||||||
|
AppendRegister(vendorBuilder, ecx);
|
||||||
|
string cpuVendor = vendorBuilder.ToString();
|
||||||
|
switch (cpuVendor) {
|
||||||
|
case "GenuineIntel":
|
||||||
|
vendor = Vendor.Intel;
|
||||||
|
break;
|
||||||
|
case "AuthenticAMD":
|
||||||
|
vendor = Vendor.AMD;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
vendor = Vendor.Unknown;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
eax = ebx = ecx = edx = 0;
|
||||||
|
if (WinRing0.CpuidTx(CPUID_EXT, 0,
|
||||||
|
out eax, out ebx, out ecx, out edx, mask))
|
||||||
|
maxCpuidExt = eax - CPUID_EXT;
|
||||||
|
} else {
|
||||||
|
throw new ArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxCpuid == 0 || maxCpuidExt == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cpuidData = new uint[maxCpuid + 1, 4];
|
||||||
|
for (uint i = 0; i < (maxCpuid + 1); i++)
|
||||||
|
WinRing0.CpuidTx(CPUID_0 + i, 0,
|
||||||
|
out cpuidData[i, 0], out cpuidData[i, 1],
|
||||||
|
out cpuidData[i, 2], out cpuidData[i, 3], mask);
|
||||||
|
|
||||||
|
cpuidExtData = new uint[MaxCpuidExt + 1, 4];
|
||||||
|
for (uint i = 0; i < (MaxCpuidExt + 1); i++)
|
||||||
|
WinRing0.CpuidTx(CPUID_EXT + i, 0,
|
||||||
|
out cpuidExtData[i, 0], out cpuidExtData[i, 1],
|
||||||
|
out cpuidExtData[i, 2], out cpuidExtData[i, 3], mask);
|
||||||
|
|
||||||
|
StringBuilder nameBuilder = new StringBuilder();
|
||||||
|
for (uint i = 2; i <= 4; i++) {
|
||||||
|
if (WinRing0.CpuidTx(CPUID_EXT + i, 0,
|
||||||
|
out eax, out ebx, out ecx, out edx, mask))
|
||||||
|
{
|
||||||
|
AppendRegister(nameBuilder, eax);
|
||||||
|
AppendRegister(nameBuilder, ebx);
|
||||||
|
AppendRegister(nameBuilder, ecx);
|
||||||
|
AppendRegister(nameBuilder, edx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nameBuilder.Replace('\0', ' ');
|
||||||
|
cpuBrandString = nameBuilder.ToString().Trim();
|
||||||
|
nameBuilder.Replace("(R)", " ");
|
||||||
|
nameBuilder.Replace("(TM)", " ");
|
||||||
|
nameBuilder.Replace("(tm)", " ");
|
||||||
|
nameBuilder.Replace("CPU", "");
|
||||||
|
for (int i = 0; i < 10; i++) nameBuilder.Replace(" ", " ");
|
||||||
|
name = nameBuilder.ToString();
|
||||||
|
if (name.Contains("@"))
|
||||||
|
name = name.Remove(name.LastIndexOf('@'));
|
||||||
|
name = name.Trim();
|
||||||
|
|
||||||
|
this.family = ((cpuidData[1, 0] & 0x0FF00000) >> 20) +
|
||||||
|
((cpuidData[1, 0] & 0x0F00) >> 8);
|
||||||
|
this.model = ((cpuidData[1, 0] & 0x0F0000) >> 12) +
|
||||||
|
((cpuidData[1, 0] & 0xF0) >> 4);
|
||||||
|
this.stepping = (cpuidData[1, 0] & 0x0F);
|
||||||
|
|
||||||
|
this.apicId = (cpuidData[1, 1] >> 24) & 0xFF;
|
||||||
|
|
||||||
|
switch (vendor) {
|
||||||
|
case Vendor.Intel:
|
||||||
|
uint maxCoreAndThreadIdPerPackage = (cpuidData[1, 1] >> 16) & 0xFF;
|
||||||
|
uint maxCoreIdPerPackage = ((cpuidData[4, 0] >> 26) & 0x3F) + 1;
|
||||||
|
threadMaskWith = (uint)Math.Ceiling(Math.Log(
|
||||||
|
maxCoreAndThreadIdPerPackage / maxCoreIdPerPackage, 2));
|
||||||
|
coreMaskWith = (uint)Math.Ceiling(Math.Log(maxCoreIdPerPackage, 2));
|
||||||
|
break;
|
||||||
|
case Vendor.AMD:
|
||||||
|
uint corePerPackage = (cpuidExtData[8, 2] & 0xFF) + 1;
|
||||||
|
threadMaskWith = 0;
|
||||||
|
coreMaskWith = (uint)Math.Ceiling(Math.Log(corePerPackage, 2));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
threadMaskWith = 0;
|
||||||
|
coreMaskWith = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
processorId = (uint)(apicId >> (int)(coreMaskWith + threadMaskWith));
|
||||||
|
coreId = (uint)((apicId >> (int)(threadMaskWith)) - processorId);
|
||||||
|
threadId = apicId - processorId - coreId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name {
|
||||||
|
get { return name; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string BrandString {
|
||||||
|
get { return cpuBrandString; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Thread {
|
||||||
|
get { return thread; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint MaxCPUID {
|
||||||
|
get { return maxCpuid; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint MaxCpuidExt {
|
||||||
|
get { return maxCpuidExt; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vendor Vendor {
|
||||||
|
get { return vendor; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint Family {
|
||||||
|
get { return family; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint Model {
|
||||||
|
get { return model; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint Stepping {
|
||||||
|
get { return stepping; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint ApicId {
|
||||||
|
get { return apicId; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint ProcessorId {
|
||||||
|
get { return processorId; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint CoreId {
|
||||||
|
get { return coreId; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint ThreadId {
|
||||||
|
get { return threadId; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint[,] Data {
|
||||||
|
get { return cpuidData; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint[,] ExtData {
|
||||||
|
get { return cpuidExtData; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -68,8 +68,7 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
[Out] SystemProcessorPerformanceInformation[] informations,
|
[Out] SystemProcessorPerformanceInformation[] informations,
|
||||||
int structSize, out IntPtr returnLength);
|
int structSize, out IntPtr returnLength);
|
||||||
|
|
||||||
private uint coreCount;
|
private CPUID[][] cpuid;
|
||||||
private uint logicalProcessorsPerCore;
|
|
||||||
|
|
||||||
private long systemTime;
|
private long systemTime;
|
||||||
private long[] idleTimes;
|
private long[] idleTimes;
|
||||||
@@ -80,7 +79,7 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
private bool available = false;
|
private bool available = false;
|
||||||
|
|
||||||
private long[] GetIdleTimes() {
|
private long[] GetIdleTimes() {
|
||||||
long[] result = new long[coreCount * logicalProcessorsPerCore];
|
long[] result = new long[cpuid.Length * cpuid[0].Length];
|
||||||
SystemProcessorPerformanceInformation[] informations = new
|
SystemProcessorPerformanceInformation[] informations = new
|
||||||
SystemProcessorPerformanceInformation[result.Length];
|
SystemProcessorPerformanceInformation[result.Length];
|
||||||
|
|
||||||
@@ -97,10 +96,9 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CPULoad(uint coreCount, uint logicalProcessorsPerCore) {
|
public CPULoad(CPUID[][] cpuid) {
|
||||||
this.coreCount = coreCount;
|
this.cpuid = cpuid;
|
||||||
this.logicalProcessorsPerCore = logicalProcessorsPerCore;
|
this.coreLoads = new float[cpuid.Length];
|
||||||
this.coreLoads = new float[coreCount];
|
|
||||||
this.systemTime = DateTime.Now.Ticks;
|
this.systemTime = DateTime.Now.Ticks;
|
||||||
this.totalLoad = 0;
|
this.totalLoad = 0;
|
||||||
try {
|
try {
|
||||||
@@ -135,21 +133,22 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
float total = 0;
|
float total = 0;
|
||||||
for (int i = 0; i < coreCount; i++) {
|
int count = 0;
|
||||||
|
for (int i = 0; i < cpuid.Length; i++) {
|
||||||
float value = 0;
|
float value = 0;
|
||||||
for (int j = 0; j < logicalProcessorsPerCore; j++) {
|
for (int j = 0; j < cpuid[i].Length; j++) {
|
||||||
long index = i * logicalProcessorsPerCore + j;
|
long index = cpuid[i][j].Thread;
|
||||||
long delta = idleTimes[index] - this.idleTimes[index];
|
long delta = idleTimes[index] - this.idleTimes[index];
|
||||||
value += delta;
|
value += delta;
|
||||||
total += delta;
|
total += delta;
|
||||||
|
count++;
|
||||||
}
|
}
|
||||||
value = 1.0f - value / (logicalProcessorsPerCore *
|
value = 1.0f - value / (cpuid[i].Length *
|
||||||
(systemTime - this.systemTime));
|
(systemTime - this.systemTime));
|
||||||
value = value < 0 ? 0 : value;
|
value = value < 0 ? 0 : value;
|
||||||
coreLoads[i] = value * 100;
|
coreLoads[i] = value * 100;
|
||||||
}
|
}
|
||||||
total = 1.0f - total / (coreCount * logicalProcessorsPerCore *
|
total = 1.0f - total / (count * (systemTime - this.systemTime));
|
||||||
(systemTime - this.systemTime));
|
|
||||||
total = total < 0 ? 0 : total;
|
total = total < 0 ? 0 : total;
|
||||||
this.totalLoad = total * 100;
|
this.totalLoad = total * 100;
|
||||||
|
|
||||||
|
@@ -48,6 +48,9 @@ using System.Text;
|
|||||||
namespace OpenHardwareMonitor.Hardware.CPU {
|
namespace OpenHardwareMonitor.Hardware.CPU {
|
||||||
public class IntelCPU : Hardware, IHardware {
|
public class IntelCPU : Hardware, IHardware {
|
||||||
|
|
||||||
|
private CPUID[][] cpuid;
|
||||||
|
private int coreCount;
|
||||||
|
|
||||||
private string name;
|
private string name;
|
||||||
private Image icon;
|
private Image icon;
|
||||||
|
|
||||||
@@ -61,14 +64,10 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
private Sensor[] coreLoads;
|
private Sensor[] coreLoads;
|
||||||
private Sensor[] coreClocks;
|
private Sensor[] coreClocks;
|
||||||
private Sensor busClock;
|
private Sensor busClock;
|
||||||
private uint logicalProcessors;
|
|
||||||
private uint logicalProcessorsPerCore;
|
|
||||||
private uint coreCount;
|
|
||||||
private bool hasTSC;
|
private bool hasTSC;
|
||||||
private bool invariantTSC;
|
private bool invariantTSC;
|
||||||
private double estimatedMaxClock;
|
private double estimatedMaxClock;
|
||||||
|
|
||||||
private ulong affinityMask;
|
|
||||||
private CPULoad cpuLoad;
|
private CPULoad cpuLoad;
|
||||||
|
|
||||||
private ulong lastTimeStampCount;
|
private ulong lastTimeStampCount;
|
||||||
@@ -87,10 +86,6 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
return "CPU Core #" + (i + 1);
|
return "CPU Core #" + (i + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
|
||||||
private static extern bool GetProcessAffinityMask(IntPtr handle,
|
|
||||||
out IntPtr processMask, out IntPtr systemMask);
|
|
||||||
|
|
||||||
private float[] Floats(float f) {
|
private float[] Floats(float f) {
|
||||||
float[] result = new float[coreCount];
|
float[] result = new float[coreCount];
|
||||||
for (int i = 0; i < coreCount; i++)
|
for (int i = 0; i < coreCount; i++)
|
||||||
@@ -98,64 +93,16 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IntelCPU(string name, uint family, uint model, uint stepping,
|
public IntelCPU(CPUID[][] cpuid) {
|
||||||
uint[,] cpuidData, uint[,] cpuidExtData) {
|
|
||||||
|
|
||||||
this.name = name;
|
this.cpuid = cpuid;
|
||||||
|
this.coreCount = cpuid.Length;
|
||||||
|
this.name = cpuid[0][0].Name;
|
||||||
this.icon = Utilities.EmbeddedResources.GetImage("cpu.png");
|
this.icon = Utilities.EmbeddedResources.GetImage("cpu.png");
|
||||||
|
|
||||||
this.family = family;
|
this.family = cpuid[0][0].Family;
|
||||||
this.model = model;
|
this.model = cpuid[0][0].Model;
|
||||||
this.stepping = stepping;
|
this.stepping = cpuid[0][0].Stepping;
|
||||||
|
|
||||||
logicalProcessors = 0;
|
|
||||||
if (cpuidData.GetLength(0) > 0x0B) {
|
|
||||||
uint eax, ebx, ecx, edx;
|
|
||||||
WinRing0.CpuidEx(0x0B, 0, out eax, out ebx, out ecx, out edx);
|
|
||||||
logicalProcessorsPerCore = ebx & 0xFF;
|
|
||||||
if (logicalProcessorsPerCore > 0) {
|
|
||||||
WinRing0.CpuidEx(0x0B, 1, out eax, out ebx, out ecx, out edx);
|
|
||||||
logicalProcessors = ebx & 0xFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (logicalProcessors <= 0 && cpuidData.GetLength(0) > 0x04) {
|
|
||||||
uint coresPerPackage = ((cpuidData[4, 0] >> 26) & 0x3F) + 1;
|
|
||||||
uint logicalPerPackage = (cpuidData[1, 1] >> 16) & 0xFF;
|
|
||||||
logicalProcessorsPerCore = logicalPerPackage / coresPerPackage;
|
|
||||||
logicalProcessors = logicalPerPackage;
|
|
||||||
}
|
|
||||||
if (logicalProcessors <= 0 && cpuidData.GetLength(0) > 0x01) {
|
|
||||||
uint logicalPerPackage = (cpuidData[1, 1] >> 16) & 0xFF;
|
|
||||||
logicalProcessorsPerCore = logicalPerPackage;
|
|
||||||
logicalProcessors = logicalPerPackage;
|
|
||||||
}
|
|
||||||
if (logicalProcessors <= 0) {
|
|
||||||
logicalProcessors = 1;
|
|
||||||
logicalProcessorsPerCore = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
IntPtr processMask, systemMask;
|
|
||||||
GetProcessAffinityMask(Process.GetCurrentProcess().Handle,
|
|
||||||
out processMask, out systemMask);
|
|
||||||
affinityMask = (ulong)systemMask;
|
|
||||||
|
|
||||||
// correct values in case HypeThreading is disabled
|
|
||||||
if (logicalProcessorsPerCore > 1) {
|
|
||||||
ulong affinity = affinityMask;
|
|
||||||
int availableLogicalProcessors = 0;
|
|
||||||
while (affinity != 0) {
|
|
||||||
if ((affinity & 0x1) > 0)
|
|
||||||
availableLogicalProcessors++;
|
|
||||||
affinity >>= 1;
|
|
||||||
}
|
|
||||||
while (logicalProcessorsPerCore > 1 &&
|
|
||||||
availableLogicalProcessors < logicalProcessors) {
|
|
||||||
logicalProcessors >>= 1;
|
|
||||||
logicalProcessorsPerCore >>= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
coreCount = logicalProcessors / logicalProcessorsPerCore;
|
|
||||||
|
|
||||||
float[] tjMax;
|
float[] tjMax;
|
||||||
switch (family) {
|
switch (family) {
|
||||||
@@ -191,8 +138,7 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
tjMax = new float[coreCount];
|
tjMax = new float[coreCount];
|
||||||
for (int i = 0; i < coreCount; i++) {
|
for (int i = 0; i < coreCount; i++) {
|
||||||
if (WinRing0.RdmsrTx(IA32_TEMPERATURE_TARGET, out eax,
|
if (WinRing0.RdmsrTx(IA32_TEMPERATURE_TARGET, out eax,
|
||||||
out edx, (UIntPtr)(
|
out edx, (UIntPtr)(1L << cpuid[i][0].Thread)))
|
||||||
1 << (int)(logicalProcessorsPerCore * i))))
|
|
||||||
{
|
{
|
||||||
tjMax[i] = (eax >> 16) & 0xFF;
|
tjMax[i] = (eax >> 16) & 0xFF;
|
||||||
} else {
|
} else {
|
||||||
@@ -211,7 +157,9 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check if processor supports a digital thermal sensor
|
// check if processor supports a digital thermal sensor
|
||||||
if (cpuidData.GetLength(0) > 6 && (cpuidData[6, 0] & 1) != 0) {
|
if (cpuid[0][0].Data.GetLength(0) > 6 &&
|
||||||
|
(cpuid[0][0].Data[6, 0] & 1) != 0)
|
||||||
|
{
|
||||||
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(CoreString(i), i, tjMax[i],
|
coreTemperatures[i] = new Sensor(CoreString(i), i, tjMax[i],
|
||||||
@@ -235,7 +183,7 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
for (int i = 0; i < coreLoads.Length; i++)
|
for (int i = 0; i < coreLoads.Length; i++)
|
||||||
coreLoads[i] = new Sensor(CoreString(i), i + 1,
|
coreLoads[i] = new Sensor(CoreString(i), i + 1,
|
||||||
SensorType.Load, this);
|
SensorType.Load, this);
|
||||||
cpuLoad = new CPULoad(coreCount, logicalProcessorsPerCore);
|
cpuLoad = new CPULoad(cpuid);
|
||||||
if (cpuLoad.IsAvailable) {
|
if (cpuLoad.IsAvailable) {
|
||||||
foreach (Sensor sensor in coreLoads)
|
foreach (Sensor sensor in coreLoads)
|
||||||
ActivateSensor(sensor);
|
ActivateSensor(sensor);
|
||||||
@@ -244,13 +192,15 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check if processor has TSC
|
// check if processor has TSC
|
||||||
if (cpuidData.GetLength(0) > 1 && (cpuidData[1, 3] & 0x10) != 0)
|
if (cpuid[0][0].Data.GetLength(0) > 1
|
||||||
|
&& (cpuid[0][0].Data[1, 3] & 0x10) != 0)
|
||||||
hasTSC = true;
|
hasTSC = true;
|
||||||
else
|
else
|
||||||
hasTSC = false;
|
hasTSC = false;
|
||||||
|
|
||||||
// check if processor supports invariant TSC
|
// check if processor supports invariant TSC
|
||||||
if (cpuidExtData.GetLength(0) > 7 && (cpuidExtData[7, 3] & 0x100) != 0)
|
if (cpuid[0][0].ExtData.GetLength(0) > 7
|
||||||
|
&& (cpuid[0][0].ExtData[7, 3] & 0x100) != 0)
|
||||||
invariantTSC = true;
|
invariantTSC = true;
|
||||||
else
|
else
|
||||||
invariantTSC = false;
|
invariantTSC = false;
|
||||||
@@ -288,10 +238,9 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
get { return icon; }
|
get { return icon; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AppendMSRData(StringBuilder r, uint msr, int core) {
|
private void AppendMSRData(StringBuilder r, uint msr, int thread) {
|
||||||
uint eax, edx;
|
uint eax, edx;
|
||||||
if (WinRing0.RdmsrTx(msr, out eax, out edx,
|
if (WinRing0.RdmsrTx(msr, out eax, out edx, (UIntPtr)(1L << thread))) {
|
||||||
(UIntPtr)(1 << (int)(logicalProcessorsPerCore * core)))) {
|
|
||||||
r.Append(" ");
|
r.Append(" ");
|
||||||
r.Append((msr).ToString("X8"));
|
r.Append((msr).ToString("X8"));
|
||||||
r.Append(" ");
|
r.Append(" ");
|
||||||
@@ -310,9 +259,7 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
r.AppendFormat("Name: {0}{1}", name, Environment.NewLine);
|
r.AppendFormat("Name: {0}{1}", name, Environment.NewLine);
|
||||||
r.AppendFormat("Number of Cores: {0}{1}", coreCount,
|
r.AppendFormat("Number of Cores: {0}{1}", coreCount,
|
||||||
Environment.NewLine);
|
Environment.NewLine);
|
||||||
r.AppendFormat("Threads per Core: {0}{1}", logicalProcessorsPerCore,
|
r.AppendFormat("Threads per Core: {0}{1}", cpuid[0].Length,
|
||||||
Environment.NewLine);
|
|
||||||
r.AppendFormat("Affinity Mask: 0x{0}{1}", affinityMask.ToString("X"),
|
|
||||||
Environment.NewLine);
|
Environment.NewLine);
|
||||||
r.AppendLine("TSC: " +
|
r.AppendLine("TSC: " +
|
||||||
(hasTSC ? (invariantTSC ? "Invariant" : "Not Invariant") : "None"));
|
(hasTSC ? (invariantTSC ? "Invariant" : "Not Invariant") : "None"));
|
||||||
@@ -322,14 +269,14 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
"Max Clock: {0} MHz", Math.Round(estimatedMaxClock * 100) * 0.01));
|
"Max Clock: {0} MHz", Math.Round(estimatedMaxClock * 100) * 0.01));
|
||||||
r.AppendLine();
|
r.AppendLine();
|
||||||
|
|
||||||
for (int i = 0; i < coreCount; i++) {
|
for (int i = 0; i < cpuid.Length; i++) {
|
||||||
r.AppendLine("MSR Core #" + (i + 1));
|
r.AppendLine("MSR Core #" + (i + 1));
|
||||||
r.AppendLine();
|
r.AppendLine();
|
||||||
r.AppendLine(" MSR EDX EAX");
|
r.AppendLine(" MSR EDX EAX");
|
||||||
AppendMSRData(r, MSR_PLATFORM_INFO, i);
|
AppendMSRData(r, MSR_PLATFORM_INFO, cpuid[i][0].Thread);
|
||||||
AppendMSRData(r, IA32_PERF_STATUS, i);
|
AppendMSRData(r, IA32_PERF_STATUS, cpuid[i][0].Thread);
|
||||||
AppendMSRData(r, IA32_THERM_STATUS_MSR, i);
|
AppendMSRData(r, IA32_THERM_STATUS_MSR, cpuid[i][0].Thread);
|
||||||
AppendMSRData(r, IA32_TEMPERATURE_TARGET, i);
|
AppendMSRData(r, IA32_TEMPERATURE_TARGET, cpuid[i][0].Thread);
|
||||||
r.AppendLine();
|
r.AppendLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -361,7 +308,7 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
uint eax, edx;
|
uint eax, edx;
|
||||||
if (WinRing0.RdmsrTx(
|
if (WinRing0.RdmsrTx(
|
||||||
IA32_THERM_STATUS_MSR, out eax, out edx,
|
IA32_THERM_STATUS_MSR, out eax, out edx,
|
||||||
(UIntPtr)(1 << (int)(logicalProcessorsPerCore * i)))) {
|
(UIntPtr)(1L << cpuid[i][0].Thread))) {
|
||||||
// if reading is valid
|
// if reading is valid
|
||||||
if ((eax & 0x80000000) != 0) {
|
if ((eax & 0x80000000) != 0) {
|
||||||
// get the dist from tjMax from bits 22:16
|
// get the dist from tjMax from bits 22:16
|
||||||
@@ -402,7 +349,7 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
|||||||
for (int i = 0; i < coreClocks.Length; i++) {
|
for (int i = 0; i < coreClocks.Length; i++) {
|
||||||
System.Threading.Thread.Sleep(1);
|
System.Threading.Thread.Sleep(1);
|
||||||
if (WinRing0.RdmsrTx(IA32_PERF_STATUS, out eax, out edx,
|
if (WinRing0.RdmsrTx(IA32_PERF_STATUS, out eax, out edx,
|
||||||
(UIntPtr)(1 << (int)(logicalProcessorsPerCore * i)))) {
|
(UIntPtr)(1L << cpuid[i][0].Thread))) {
|
||||||
if (maxNehalemMultiplier > 0) { // Core i3, i5, i7
|
if (maxNehalemMultiplier > 0) { // Core i3, i5, i7
|
||||||
uint nehalemMultiplier = eax & 0xff;
|
uint nehalemMultiplier = eax & 0xff;
|
||||||
coreClocks[i].Value =
|
coreClocks[i].Value =
|
||||||
|
@@ -79,10 +79,11 @@ namespace OpenHardwareMonitor.Hardware {
|
|||||||
|
|
||||||
public delegate uint GetDllStatusDelegate();
|
public delegate uint GetDllStatusDelegate();
|
||||||
public delegate bool IsCpuidDelegate();
|
public delegate bool IsCpuidDelegate();
|
||||||
public delegate bool CpuidDelegate(uint index,
|
public delegate bool CpuidDelegate(uint index, uint ecxValue,
|
||||||
out uint eax, out uint ebx, out uint ecx, out uint edx);
|
|
||||||
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 CpuidTxDelegate(uint index, uint ecxValue,
|
||||||
|
out uint eax, out uint ebx, out uint ecx, out uint edx,
|
||||||
|
UIntPtr threadAffinityMask);
|
||||||
public delegate bool RdmsrDelegate(uint index, out uint eax, out uint edx);
|
public delegate bool RdmsrDelegate(uint index, out uint eax, out uint edx);
|
||||||
public delegate bool RdmsrTxDelegate(uint index, out uint eax, out uint edx,
|
public delegate bool RdmsrTxDelegate(uint index, out uint eax, out uint edx,
|
||||||
UIntPtr threadAffinityMask);
|
UIntPtr threadAffinityMask);
|
||||||
@@ -105,7 +106,7 @@ namespace OpenHardwareMonitor.Hardware {
|
|||||||
public static GetDllStatusDelegate GetDllStatus;
|
public static GetDllStatusDelegate GetDllStatus;
|
||||||
public static IsCpuidDelegate IsCpuid;
|
public static IsCpuidDelegate IsCpuid;
|
||||||
public static CpuidDelegate Cpuid;
|
public static CpuidDelegate Cpuid;
|
||||||
public static CpuidExDelegate CpuidEx;
|
public static CpuidTxDelegate CpuidTx;
|
||||||
public static RdmsrDelegate Rdmsr;
|
public static RdmsrDelegate Rdmsr;
|
||||||
public static RdmsrTxDelegate RdmsrTx;
|
public static RdmsrTxDelegate RdmsrTx;
|
||||||
public static ReadIoPortByteDelegate ReadIoPortByte;
|
public static ReadIoPortByteDelegate ReadIoPortByte;
|
||||||
@@ -134,7 +135,7 @@ namespace OpenHardwareMonitor.Hardware {
|
|||||||
GetDelegate("GetDllStatus", out GetDllStatus);
|
GetDelegate("GetDllStatus", out GetDllStatus);
|
||||||
GetDelegate("IsCpuid", out IsCpuid);
|
GetDelegate("IsCpuid", out IsCpuid);
|
||||||
GetDelegate("Cpuid", out Cpuid);
|
GetDelegate("Cpuid", out Cpuid);
|
||||||
GetDelegate("CpuidEx", out CpuidEx);
|
GetDelegate("CpuidTx", out CpuidTx);
|
||||||
GetDelegate("Rdmsr", out Rdmsr);
|
GetDelegate("Rdmsr", out Rdmsr);
|
||||||
GetDelegate("RdmsrTx", out RdmsrTx);
|
GetDelegate("RdmsrTx", out RdmsrTx);
|
||||||
GetDelegate("ReadIoPortByte", out ReadIoPortByte);
|
GetDelegate("ReadIoPortByte", out ReadIoPortByte);
|
||||||
|
@@ -78,6 +78,7 @@
|
|||||||
<Compile Include="GUI\TypeNode.cs" />
|
<Compile Include="GUI\TypeNode.cs" />
|
||||||
<Compile Include="Hardware\CPU\AMD10CPU.cs" />
|
<Compile Include="Hardware\CPU\AMD10CPU.cs" />
|
||||||
<Compile Include="Hardware\CPU\AMD0FCPU.cs" />
|
<Compile Include="Hardware\CPU\AMD0FCPU.cs" />
|
||||||
|
<Compile Include="Hardware\CPU\CPUID.cs" />
|
||||||
<Compile Include="Hardware\CPU\CPULoad.cs" />
|
<Compile Include="Hardware\CPU\CPULoad.cs" />
|
||||||
<Compile Include="Hardware\Hardware.cs" />
|
<Compile Include="Hardware\Hardware.cs" />
|
||||||
<Compile Include="Hardware\HDD\HDD.cs" />
|
<Compile Include="Hardware\HDD\HDD.cs" />
|
||||||
|
Reference in New Issue
Block a user