# HG changeset patch # User moel.mich # Date 1272139192 0 # Node ID 3333b29a174693539c7f533f015d962bd0de724c # Parent 62e0b6011e8c825541dec89077ea139754aff2fb Implemented APIC based CPU enumeration (Issue 41). diff -r 62e0b6011e8c -r 3333b29a1746 External/WinRing0.dll Binary file External/WinRing0.dll has changed diff -r 62e0b6011e8c -r 3333b29a1746 External/WinRing0x64.dll Binary file External/WinRing0x64.dll has changed diff -r 62e0b6011e8c -r 3333b29a1746 Hardware/CPU/AMD0FCPU.cs --- a/Hardware/CPU/AMD0FCPU.cs Mon Apr 05 21:31:21 2010 +0000 +++ b/Hardware/CPU/AMD0FCPU.cs Sat Apr 24 19:59:52 2010 +0000 @@ -63,41 +63,46 @@ private const byte THERM_SENSE_CORE_SEL_CPU0 = 0x4; private const byte THERM_SENSE_CORE_SEL_CPU1 = 0x0; - public AMD0FCPU(string name, uint family, uint model, uint stepping, - uint[,] cpuidData, uint[,] cpuidExtData) { - - this.name = name; - this.icon = Utilities.EmbeddedResources.GetImage("cpu.png"); + public AMD0FCPU(CPUID[][] cpuid) { - uint coreCount = 1; - if (cpuidExtData.GetLength(0) > 8) - coreCount = (cpuidExtData[8, 2] & 0xFF) + 1; + this.name = cpuid[0][0].Name; + this.icon = Utilities.EmbeddedResources.GetImage("cpu.png"); - // max two cores - coreCount = coreCount > 2 ? 2 : coreCount; + int coreCount = cpuid.Length; totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this); float offset = -49.0f; // AM2+ 65nm +21 offset + uint model = cpuid[0][0].Model; if (model >= 0x69 && model != 0xc1 && model != 0x6c && model != 0x7c) offset += 21; - coreTemperatures = new Sensor[coreCount]; - coreLoads = new Sensor[coreCount]; - for (int i = 0; i < coreCount; i++) { - coreTemperatures[i] = - 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) + // check if processor supports a digital thermal sensor + if (cpuid[0][0].ExtData.GetLength(0) > 7 && + (cpuid[0][0].ExtData[7, 3] & 1) != 0) + { + coreTemperatures = new Sensor[coreCount]; + for (int i = 0; i < coreCount; i++) { + coreTemperatures[i] = + 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) { foreach (Sensor sensor in coreLoads) ActivateSensor(sensor); @@ -128,7 +133,6 @@ public void Update() { if (pciAddress != 0xFFFFFFFF) { - for (uint i = 0; i < coreTemperatures.Length; i++) { if (WinRing0.WritePciConfigDwordEx( pciAddress, THERMTRIP_STATUS_REGISTER, diff -r 62e0b6011e8c -r 3333b29a1746 Hardware/CPU/AMD10CPU.cs --- a/Hardware/CPU/AMD10CPU.cs Mon Apr 05 21:31:21 2010 +0000 +++ b/Hardware/CPU/AMD10CPU.cs Sat Apr 24 19:59:52 2010 +0000 @@ -60,15 +60,12 @@ private const ushort PCI_AMD_11H_MISCELLANEOUS_DEVICE_ID = 0x1303; private const uint REPORTED_TEMPERATURE_CONTROL_REGISTER = 0xA4; - public AMD10CPU(string name, uint family, uint model, uint stepping, - uint[,] cpuidData, uint[,] cpuidExtData) { - - this.name = name; - this.icon = Utilities.EmbeddedResources.GetImage("cpu.png"); + public AMD10CPU(CPUID[][] cpuid) { - uint coreCount = 1; - if (cpuidExtData.GetLength(0) > 8) - coreCount = (cpuidExtData[8, 2] & 0xFF) + 1; + this.name = cpuid[0][0].Name; + this.icon = Utilities.EmbeddedResources.GetImage("cpu.png"); + + int coreCount = cpuid.Length; totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this); @@ -77,7 +74,7 @@ coreLoads[i] = new Sensor("Core #" + (i + 1), i + 1, SensorType.Load, this); - cpuLoad = new CPULoad(coreCount, 1); + cpuLoad = new CPULoad(cpuid); if (cpuLoad.IsAvailable) { foreach (Sensor sensor in coreLoads) ActivateSensor(sensor); diff -r 62e0b6011e8c -r 3333b29a1746 Hardware/CPU/CPUGroup.cs --- a/Hardware/CPU/CPUGroup.cs Mon Apr 05 21:31:21 2010 +0000 +++ b/Hardware/CPU/CPUGroup.cs Sat Apr 24 19:59:52 2010 +0000 @@ -37,6 +37,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Text; namespace OpenHardwareMonitor.Hardware.CPU { @@ -44,119 +45,99 @@ public class CPUGroup : IGroup { private List hardware = new List(); - private string cpuBrandString; - private string cpuVendor; - private uint[,] cpuidData; - private uint[,] cpuidExtData; + private CPUID[][][] threads; - private uint family; - private uint model; - private uint stepping; + private CPUID[][] GetProcessorThreads() { - private static uint CPUID = 0; - private static uint CPUID_EXT = 0x80000000; + List threads = new List(); + for (int i = 0; i < 32; i++) { + try { + threads.Add(new CPUID(i)); + } catch (ArgumentException) { } + } - public static 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)); + SortedDictionary> processors = + new SortedDictionary>(); + foreach (CPUID thread in threads) { + List list; + processors.TryGetValue(thread.ProcessorId, out list); + if (list == null) { + list = new List(); + processors.Add(thread.ProcessorId, list); + } + list.Add(thread); + } + + CPUID[][] processorThreads = new CPUID[processors.Count][]; + int index = 0; + foreach (List list in processors.Values) { + processorThreads[index] = list.ToArray(); + index++; + } + return processorThreads; + } + + private CPUID[][] GroupThreadsByCore(CPUID[] threads) { + + SortedDictionary> cores = + new SortedDictionary>(); + foreach (CPUID thread in threads) { + List coreList; + cores.TryGetValue(thread.CoreId, out coreList); + if (coreList == null) { + coreList = new List(); + cores.Add(thread.CoreId, coreList); + } + coreList.Add(thread); + } + + CPUID[][] coreThreads = new CPUID[cores.Count][]; + int index = 0; + foreach (List list in cores.Values) { + coreThreads[index] = list.ToArray(); + index++; + } + return coreThreads; } public CPUGroup() { - - if (!WinRing0.IsAvailable) + if (!WinRing0.IsCpuid()) return; - if (WinRing0.IsCpuid()) { - uint maxCPUID = 0; - uint maxCPUID_EXT = 0; - uint eax, ebx, ecx, edx; + CPUID[][] processorThreads = GetProcessorThreads(); + this.threads = new CPUID[processorThreads.Length][][]; - - if (WinRing0.Cpuid(CPUID, out eax, out ebx, out ecx, out edx)) { - maxCPUID = eax; - StringBuilder vendorBuilder = new StringBuilder(); - AppendRegister(vendorBuilder, ebx); - AppendRegister(vendorBuilder, edx); - AppendRegister(vendorBuilder, ecx); - cpuVendor = vendorBuilder.ToString(); + int index = 0; + foreach (CPUID[] threads in processorThreads) { + if (threads.Length == 0) + continue; + + CPUID[][] coreThreads = GroupThreadsByCore(threads); - eax = ebx = ecx = edx = 0; - if (WinRing0.Cpuid(CPUID_EXT, out eax, out ebx, out ecx, out edx)) { - maxCPUID_EXT = eax - CPUID_EXT; - } - } - if (maxCPUID == 0 || maxCPUID_EXT == 0) - return; + this.threads[index] = coreThreads; + index++; - cpuidData = new uint[maxCPUID + 1, 4]; - for (uint i = 0; i < (maxCPUID + 1); i++) - WinRing0.Cpuid(CPUID + i, out cpuidData[i, 0], out cpuidData[i, 1], - 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)); + switch (threads[0].Vendor) { + case Vendor.Intel: + hardware.Add(new IntelCPU(coreThreads)); 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; + 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: break; - } + } } } - + public IHardware[] Hardware { get { return hardware.ToArray(); @@ -178,32 +159,43 @@ public string GetReport() { StringBuilder r = new StringBuilder(); - + r.AppendLine("CPUID"); 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"); - r.AppendLine(); + for (int i = 0; i < threads.Length; i++) { - if (cpuidData != null) { - r.AppendLine(" Function EAX EBX ECX EDX"); - AppendCpuidData(r, cpuidData, CPUID); - AppendCpuidData(r, cpuidExtData, CPUID_EXT); + r.AppendLine("Processor " + i); r.AppendLine(); + r.AppendFormat("Processor Vendor: {0}{1}", threads[i][0][0].Vendor, + 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("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(); } public void Close() { } diff -r 62e0b6011e8c -r 3333b29a1746 Hardware/CPU/CPUID.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Hardware/CPU/CPUID.cs Sat Apr 24 19:59:52 2010 +0000 @@ -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 . + 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; } + } + } +} diff -r 62e0b6011e8c -r 3333b29a1746 Hardware/CPU/CPULoad.cs --- a/Hardware/CPU/CPULoad.cs Mon Apr 05 21:31:21 2010 +0000 +++ b/Hardware/CPU/CPULoad.cs Sat Apr 24 19:59:52 2010 +0000 @@ -68,8 +68,7 @@ [Out] SystemProcessorPerformanceInformation[] informations, int structSize, out IntPtr returnLength); - private uint coreCount; - private uint logicalProcessorsPerCore; + private CPUID[][] cpuid; private long systemTime; private long[] idleTimes; @@ -80,7 +79,7 @@ private bool available = false; private long[] GetIdleTimes() { - long[] result = new long[coreCount * logicalProcessorsPerCore]; + long[] result = new long[cpuid.Length * cpuid[0].Length]; SystemProcessorPerformanceInformation[] informations = new SystemProcessorPerformanceInformation[result.Length]; @@ -97,10 +96,9 @@ return result; } - public CPULoad(uint coreCount, uint logicalProcessorsPerCore) { - this.coreCount = coreCount; - this.logicalProcessorsPerCore = logicalProcessorsPerCore; - this.coreLoads = new float[coreCount]; + public CPULoad(CPUID[][] cpuid) { + this.cpuid = cpuid; + this.coreLoads = new float[cpuid.Length]; this.systemTime = DateTime.Now.Ticks; this.totalLoad = 0; try { @@ -135,21 +133,22 @@ return; float total = 0; - for (int i = 0; i < coreCount; i++) { + int count = 0; + for (int i = 0; i < cpuid.Length; i++) { float value = 0; - for (int j = 0; j < logicalProcessorsPerCore; j++) { - long index = i * logicalProcessorsPerCore + j; + for (int j = 0; j < cpuid[i].Length; j++) { + long index = cpuid[i][j].Thread; long delta = idleTimes[index] - this.idleTimes[index]; value += delta; total += delta; + count++; } - value = 1.0f - value / (logicalProcessorsPerCore * + value = 1.0f - value / (cpuid[i].Length * (systemTime - this.systemTime)); value = value < 0 ? 0 : value; coreLoads[i] = value * 100; } - total = 1.0f - total / (coreCount * logicalProcessorsPerCore * - (systemTime - this.systemTime)); + total = 1.0f - total / (count * (systemTime - this.systemTime)); total = total < 0 ? 0 : total; this.totalLoad = total * 100; diff -r 62e0b6011e8c -r 3333b29a1746 Hardware/CPU/IntelCPU.cs --- a/Hardware/CPU/IntelCPU.cs Mon Apr 05 21:31:21 2010 +0000 +++ b/Hardware/CPU/IntelCPU.cs Sat Apr 24 19:59:52 2010 +0000 @@ -48,6 +48,9 @@ namespace OpenHardwareMonitor.Hardware.CPU { public class IntelCPU : Hardware, IHardware { + private CPUID[][] cpuid; + private int coreCount; + private string name; private Image icon; @@ -60,15 +63,11 @@ private Sensor totalLoad; private Sensor[] coreLoads; private Sensor[] coreClocks; - private Sensor busClock; - private uint logicalProcessors; - private uint logicalProcessorsPerCore; - private uint coreCount; + private Sensor busClock; private bool hasTSC; private bool invariantTSC; private double estimatedMaxClock; - private ulong affinityMask; private CPULoad cpuLoad; private ulong lastTimeStampCount; @@ -87,10 +86,6 @@ 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) { float[] result = new float[coreCount]; for (int i = 0; i < coreCount; i++) @@ -98,64 +93,16 @@ return result; } - public IntelCPU(string name, uint family, uint model, uint stepping, - uint[,] cpuidData, uint[,] cpuidExtData) { - - this.name = name; + public IntelCPU(CPUID[][] cpuid) { + + this.cpuid = cpuid; + this.coreCount = cpuid.Length; + this.name = cpuid[0][0].Name; this.icon = Utilities.EmbeddedResources.GetImage("cpu.png"); - this.family = family; - this.model = model; - this.stepping = 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; + this.family = cpuid[0][0].Family; + this.model = cpuid[0][0].Model; + this.stepping = cpuid[0][0].Stepping; float[] tjMax; switch (family) { @@ -191,8 +138,7 @@ tjMax = new float[coreCount]; for (int i = 0; i < coreCount; i++) { if (WinRing0.RdmsrTx(IA32_TEMPERATURE_TARGET, out eax, - out edx, (UIntPtr)( - 1 << (int)(logicalProcessorsPerCore * i)))) + out edx, (UIntPtr)(1L << cpuid[i][0].Thread))) { tjMax[i] = (eax >> 16) & 0xFF; } else { @@ -211,7 +157,9 @@ } // 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]; for (int i = 0; i < coreTemperatures.Length; i++) { coreTemperatures[i] = new Sensor(CoreString(i), i, tjMax[i], @@ -235,7 +183,7 @@ for (int i = 0; i < coreLoads.Length; i++) coreLoads[i] = new Sensor(CoreString(i), i + 1, SensorType.Load, this); - cpuLoad = new CPULoad(coreCount, logicalProcessorsPerCore); + cpuLoad = new CPULoad(cpuid); if (cpuLoad.IsAvailable) { foreach (Sensor sensor in coreLoads) ActivateSensor(sensor); @@ -244,13 +192,15 @@ } // 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; else hasTSC = false; // 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; else invariantTSC = false; @@ -288,10 +238,9 @@ get { return icon; } } - private void AppendMSRData(StringBuilder r, uint msr, int core) { + private void AppendMSRData(StringBuilder r, uint msr, int thread) { uint eax, edx; - if (WinRing0.RdmsrTx(msr, out eax, out edx, - (UIntPtr)(1 << (int)(logicalProcessorsPerCore * core)))) { + if (WinRing0.RdmsrTx(msr, out eax, out edx, (UIntPtr)(1L << thread))) { r.Append(" "); r.Append((msr).ToString("X8")); r.Append(" "); @@ -310,10 +259,8 @@ r.AppendFormat("Name: {0}{1}", name, Environment.NewLine); r.AppendFormat("Number of Cores: {0}{1}", coreCount, Environment.NewLine); - r.AppendFormat("Threads per Core: {0}{1}", logicalProcessorsPerCore, - Environment.NewLine); - r.AppendFormat("Affinity Mask: 0x{0}{1}", affinityMask.ToString("X"), - Environment.NewLine); + r.AppendFormat("Threads per Core: {0}{1}", cpuid[0].Length, + Environment.NewLine); r.AppendLine("TSC: " + (hasTSC ? (invariantTSC ? "Invariant" : "Not Invariant") : "None")); r.AppendLine(string.Format(CultureInfo.InvariantCulture, @@ -322,14 +269,14 @@ "Max Clock: {0} MHz", Math.Round(estimatedMaxClock * 100) * 0.01)); 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(); r.AppendLine(" MSR EDX EAX"); - AppendMSRData(r, MSR_PLATFORM_INFO, i); - AppendMSRData(r, IA32_PERF_STATUS, i); - AppendMSRData(r, IA32_THERM_STATUS_MSR, i); - AppendMSRData(r, IA32_TEMPERATURE_TARGET, i); + AppendMSRData(r, MSR_PLATFORM_INFO, cpuid[i][0].Thread); + AppendMSRData(r, IA32_PERF_STATUS, cpuid[i][0].Thread); + AppendMSRData(r, IA32_THERM_STATUS_MSR, cpuid[i][0].Thread); + AppendMSRData(r, IA32_TEMPERATURE_TARGET, cpuid[i][0].Thread); r.AppendLine(); } @@ -360,8 +307,8 @@ for (int i = 0; i < coreTemperatures.Length; i++) { uint eax, edx; if (WinRing0.RdmsrTx( - IA32_THERM_STATUS_MSR, out eax, out edx, - (UIntPtr)(1 << (int)(logicalProcessorsPerCore * i)))) { + IA32_THERM_STATUS_MSR, out eax, out edx, + (UIntPtr)(1L << cpuid[i][0].Thread))) { // if reading is valid if ((eax & 0x80000000) != 0) { // get the dist from tjMax from bits 22:16 @@ -402,7 +349,7 @@ for (int i = 0; i < coreClocks.Length; i++) { System.Threading.Thread.Sleep(1); 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 uint nehalemMultiplier = eax & 0xff; coreClocks[i].Value = diff -r 62e0b6011e8c -r 3333b29a1746 Hardware/WinRing0.cs --- a/Hardware/WinRing0.cs Mon Apr 05 21:31:21 2010 +0000 +++ b/Hardware/WinRing0.cs Sat Apr 24 19:59:52 2010 +0000 @@ -79,10 +79,11 @@ public delegate uint GetDllStatusDelegate(); 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); + 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 RdmsrTxDelegate(uint index, out uint eax, out uint edx, UIntPtr threadAffinityMask); @@ -105,7 +106,7 @@ public static GetDllStatusDelegate GetDllStatus; public static IsCpuidDelegate IsCpuid; public static CpuidDelegate Cpuid; - public static CpuidExDelegate CpuidEx; + public static CpuidTxDelegate CpuidTx; public static RdmsrDelegate Rdmsr; public static RdmsrTxDelegate RdmsrTx; public static ReadIoPortByteDelegate ReadIoPortByte; @@ -134,7 +135,7 @@ GetDelegate("GetDllStatus", out GetDllStatus); GetDelegate("IsCpuid", out IsCpuid); GetDelegate("Cpuid", out Cpuid); - GetDelegate("CpuidEx", out CpuidEx); + GetDelegate("CpuidTx", out CpuidTx); GetDelegate("Rdmsr", out Rdmsr); GetDelegate("RdmsrTx", out RdmsrTx); GetDelegate("ReadIoPortByte", out ReadIoPortByte); diff -r 62e0b6011e8c -r 3333b29a1746 OpenHardwareMonitor.csproj --- a/OpenHardwareMonitor.csproj Mon Apr 05 21:31:21 2010 +0000 +++ b/OpenHardwareMonitor.csproj Sat Apr 24 19:59:52 2010 +0000 @@ -78,6 +78,7 @@ +