Implemented APIC based CPU enumeration (Issue 41).
1.1 Binary file External/WinRing0.dll has changed
2.1 Binary file External/WinRing0x64.dll has changed
3.1 --- a/Hardware/CPU/AMD0FCPU.cs Mon Apr 05 21:31:21 2010 +0000
3.2 +++ b/Hardware/CPU/AMD0FCPU.cs Sat Apr 24 19:59:52 2010 +0000
3.3 @@ -63,41 +63,46 @@
3.4 private const byte THERM_SENSE_CORE_SEL_CPU0 = 0x4;
3.5 private const byte THERM_SENSE_CORE_SEL_CPU1 = 0x0;
3.6
3.7 - public AMD0FCPU(string name, uint family, uint model, uint stepping,
3.8 - uint[,] cpuidData, uint[,] cpuidExtData) {
3.9 -
3.10 - this.name = name;
3.11 - this.icon = Utilities.EmbeddedResources.GetImage("cpu.png");
3.12 + public AMD0FCPU(CPUID[][] cpuid) {
3.13
3.14 - uint coreCount = 1;
3.15 - if (cpuidExtData.GetLength(0) > 8)
3.16 - coreCount = (cpuidExtData[8, 2] & 0xFF) + 1;
3.17 + this.name = cpuid[0][0].Name;
3.18 + this.icon = Utilities.EmbeddedResources.GetImage("cpu.png");
3.19
3.20 - // max two cores
3.21 - coreCount = coreCount > 2 ? 2 : coreCount;
3.22 + int coreCount = cpuid.Length;
3.23
3.24 totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this);
3.25
3.26 float offset = -49.0f;
3.27
3.28 // AM2+ 65nm +21 offset
3.29 + uint model = cpuid[0][0].Model;
3.30 if (model >= 0x69 && model != 0xc1 && model != 0x6c && model != 0x7c)
3.31 offset += 21;
3.32
3.33 - coreTemperatures = new Sensor[coreCount];
3.34 - coreLoads = new Sensor[coreCount];
3.35 - for (int i = 0; i < coreCount; i++) {
3.36 - coreTemperatures[i] =
3.37 - new Sensor("Core #" + (i + 1), i, null, SensorType.Temperature, this,
3.38 - new ParameterDescription[] { new ParameterDescription("Offset",
3.39 - "Temperature offset of the thermal sensor.\n" +
3.40 - "Temperature = Value + Offset.", offset)
3.41 + // check if processor supports a digital thermal sensor
3.42 + if (cpuid[0][0].ExtData.GetLength(0) > 7 &&
3.43 + (cpuid[0][0].ExtData[7, 3] & 1) != 0)
3.44 + {
3.45 + coreTemperatures = new Sensor[coreCount];
3.46 + for (int i = 0; i < coreCount; i++) {
3.47 + coreTemperatures[i] =
3.48 + new Sensor("Core #" + (i + 1), i, null, SensorType.Temperature,
3.49 + this, new ParameterDescription[] {
3.50 + new ParameterDescription("Offset",
3.51 + "Temperature offset of the thermal sensor.\n" +
3.52 + "Temperature = Value + Offset.", offset)
3.53 });
3.54 - coreLoads[i] = new Sensor("Core #" + (i + 1), i + 1,
3.55 - SensorType.Load, this);
3.56 + }
3.57 + } else {
3.58 + coreTemperatures = new Sensor[0];
3.59 }
3.60
3.61 - cpuLoad = new CPULoad(coreCount, 1);
3.62 + coreLoads = new Sensor[coreCount];
3.63 + for (int i = 0; i < coreCount; i++)
3.64 + coreLoads[i] = new Sensor("Core #" + (i + 1), i + 1,
3.65 + SensorType.Load, this);
3.66 +
3.67 + cpuLoad = new CPULoad(cpuid);
3.68 if (cpuLoad.IsAvailable) {
3.69 foreach (Sensor sensor in coreLoads)
3.70 ActivateSensor(sensor);
3.71 @@ -128,7 +133,6 @@
3.72
3.73 public void Update() {
3.74 if (pciAddress != 0xFFFFFFFF) {
3.75 -
3.76 for (uint i = 0; i < coreTemperatures.Length; i++) {
3.77 if (WinRing0.WritePciConfigDwordEx(
3.78 pciAddress, THERMTRIP_STATUS_REGISTER,
4.1 --- a/Hardware/CPU/AMD10CPU.cs Mon Apr 05 21:31:21 2010 +0000
4.2 +++ b/Hardware/CPU/AMD10CPU.cs Sat Apr 24 19:59:52 2010 +0000
4.3 @@ -60,15 +60,12 @@
4.4 private const ushort PCI_AMD_11H_MISCELLANEOUS_DEVICE_ID = 0x1303;
4.5 private const uint REPORTED_TEMPERATURE_CONTROL_REGISTER = 0xA4;
4.6
4.7 - public AMD10CPU(string name, uint family, uint model, uint stepping,
4.8 - uint[,] cpuidData, uint[,] cpuidExtData) {
4.9 -
4.10 - this.name = name;
4.11 - this.icon = Utilities.EmbeddedResources.GetImage("cpu.png");
4.12 + public AMD10CPU(CPUID[][] cpuid) {
4.13
4.14 - uint coreCount = 1;
4.15 - if (cpuidExtData.GetLength(0) > 8)
4.16 - coreCount = (cpuidExtData[8, 2] & 0xFF) + 1;
4.17 + this.name = cpuid[0][0].Name;
4.18 + this.icon = Utilities.EmbeddedResources.GetImage("cpu.png");
4.19 +
4.20 + int coreCount = cpuid.Length;
4.21
4.22 totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this);
4.23
4.24 @@ -77,7 +74,7 @@
4.25 coreLoads[i] = new Sensor("Core #" + (i + 1), i + 1,
4.26 SensorType.Load, this);
4.27
4.28 - cpuLoad = new CPULoad(coreCount, 1);
4.29 + cpuLoad = new CPULoad(cpuid);
4.30 if (cpuLoad.IsAvailable) {
4.31 foreach (Sensor sensor in coreLoads)
4.32 ActivateSensor(sensor);
5.1 --- a/Hardware/CPU/CPUGroup.cs Mon Apr 05 21:31:21 2010 +0000
5.2 +++ b/Hardware/CPU/CPUGroup.cs Sat Apr 24 19:59:52 2010 +0000
5.3 @@ -37,6 +37,7 @@
5.4
5.5 using System;
5.6 using System.Collections.Generic;
5.7 +using System.Diagnostics;
5.8 using System.Text;
5.9
5.10 namespace OpenHardwareMonitor.Hardware.CPU {
5.11 @@ -44,119 +45,99 @@
5.12 public class CPUGroup : IGroup {
5.13 private List<IHardware> hardware = new List<IHardware>();
5.14
5.15 - private string cpuBrandString;
5.16 - private string cpuVendor;
5.17 - private uint[,] cpuidData;
5.18 - private uint[,] cpuidExtData;
5.19 + private CPUID[][][] threads;
5.20
5.21 - private uint family;
5.22 - private uint model;
5.23 - private uint stepping;
5.24 + private CPUID[][] GetProcessorThreads() {
5.25
5.26 - private static uint CPUID = 0;
5.27 - private static uint CPUID_EXT = 0x80000000;
5.28 + List<CPUID> threads = new List<CPUID>();
5.29 + for (int i = 0; i < 32; i++) {
5.30 + try {
5.31 + threads.Add(new CPUID(i));
5.32 + } catch (ArgumentException) { }
5.33 + }
5.34
5.35 - public static void AppendRegister(StringBuilder b, uint value) {
5.36 - b.Append((char)((value) & 0xff));
5.37 - b.Append((char)((value >> 8) & 0xff));
5.38 - b.Append((char)((value >> 16) & 0xff));
5.39 - b.Append((char)((value >> 24) & 0xff));
5.40 + SortedDictionary<uint, List<CPUID>> processors =
5.41 + new SortedDictionary<uint, List<CPUID>>();
5.42 + foreach (CPUID thread in threads) {
5.43 + List<CPUID> list;
5.44 + processors.TryGetValue(thread.ProcessorId, out list);
5.45 + if (list == null) {
5.46 + list = new List<CPUID>();
5.47 + processors.Add(thread.ProcessorId, list);
5.48 + }
5.49 + list.Add(thread);
5.50 + }
5.51 +
5.52 + CPUID[][] processorThreads = new CPUID[processors.Count][];
5.53 + int index = 0;
5.54 + foreach (List<CPUID> list in processors.Values) {
5.55 + processorThreads[index] = list.ToArray();
5.56 + index++;
5.57 + }
5.58 + return processorThreads;
5.59 + }
5.60 +
5.61 + private CPUID[][] GroupThreadsByCore(CPUID[] threads) {
5.62 +
5.63 + SortedDictionary<uint, List<CPUID>> cores =
5.64 + new SortedDictionary<uint, List<CPUID>>();
5.65 + foreach (CPUID thread in threads) {
5.66 + List<CPUID> coreList;
5.67 + cores.TryGetValue(thread.CoreId, out coreList);
5.68 + if (coreList == null) {
5.69 + coreList = new List<CPUID>();
5.70 + cores.Add(thread.CoreId, coreList);
5.71 + }
5.72 + coreList.Add(thread);
5.73 + }
5.74 +
5.75 + CPUID[][] coreThreads = new CPUID[cores.Count][];
5.76 + int index = 0;
5.77 + foreach (List<CPUID> list in cores.Values) {
5.78 + coreThreads[index] = list.ToArray();
5.79 + index++;
5.80 + }
5.81 + return coreThreads;
5.82 }
5.83
5.84 public CPUGroup() {
5.85 -
5.86 - if (!WinRing0.IsAvailable)
5.87 + if (!WinRing0.IsCpuid())
5.88 return;
5.89
5.90 - if (WinRing0.IsCpuid()) {
5.91 - uint maxCPUID = 0;
5.92 - uint maxCPUID_EXT = 0;
5.93 - uint eax, ebx, ecx, edx;
5.94 + CPUID[][] processorThreads = GetProcessorThreads();
5.95 + this.threads = new CPUID[processorThreads.Length][][];
5.96
5.97 -
5.98 - if (WinRing0.Cpuid(CPUID, out eax, out ebx, out ecx, out edx)) {
5.99 - maxCPUID = eax;
5.100 - StringBuilder vendorBuilder = new StringBuilder();
5.101 - AppendRegister(vendorBuilder, ebx);
5.102 - AppendRegister(vendorBuilder, edx);
5.103 - AppendRegister(vendorBuilder, ecx);
5.104 - cpuVendor = vendorBuilder.ToString();
5.105 + int index = 0;
5.106 + foreach (CPUID[] threads in processorThreads) {
5.107 + if (threads.Length == 0)
5.108 + continue;
5.109 +
5.110 + CPUID[][] coreThreads = GroupThreadsByCore(threads);
5.111
5.112 - eax = ebx = ecx = edx = 0;
5.113 - if (WinRing0.Cpuid(CPUID_EXT, out eax, out ebx, out ecx, out edx)) {
5.114 - maxCPUID_EXT = eax - CPUID_EXT;
5.115 - }
5.116 - }
5.117 - if (maxCPUID == 0 || maxCPUID_EXT == 0)
5.118 - return;
5.119 + this.threads[index] = coreThreads;
5.120 + index++;
5.121
5.122 - cpuidData = new uint[maxCPUID + 1, 4];
5.123 - for (uint i = 0; i < (maxCPUID + 1); i++)
5.124 - WinRing0.Cpuid(CPUID + i, out cpuidData[i, 0], out cpuidData[i, 1],
5.125 - out cpuidData[i, 2], out cpuidData[i, 3]);
5.126 -
5.127 - cpuidExtData = new uint[maxCPUID_EXT + 1, 4];
5.128 - for (uint i = 0; i < (maxCPUID_EXT + 1); i++)
5.129 - WinRing0.Cpuid(CPUID_EXT + i, out cpuidExtData[i, 0],
5.130 - out cpuidExtData[i, 1], out cpuidExtData[i, 2],
5.131 - out cpuidExtData[i, 3]);
5.132 -
5.133 - StringBuilder nameBuilder = new StringBuilder();
5.134 - for (uint i = 2; i <= 4; i++) {
5.135 - if (WinRing0.Cpuid(CPUID_EXT + i, out eax, out ebx, out ecx, out edx))
5.136 - {
5.137 - AppendRegister(nameBuilder, eax);
5.138 - AppendRegister(nameBuilder, ebx);
5.139 - AppendRegister(nameBuilder, ecx);
5.140 - AppendRegister(nameBuilder, edx);
5.141 - }
5.142 - }
5.143 - nameBuilder.Replace('\0', ' ');
5.144 - cpuBrandString = nameBuilder.ToString().Trim();
5.145 - nameBuilder.Replace("(R)", " ");
5.146 - nameBuilder.Replace("(TM)", " ");
5.147 - nameBuilder.Replace("(tm)", " ");
5.148 - nameBuilder.Replace("CPU", "");
5.149 - for (int i = 0; i < 10; i++) nameBuilder.Replace(" ", " ");
5.150 - string name = nameBuilder.ToString();
5.151 - if (name.Contains("@"))
5.152 - name = name.Remove(name.LastIndexOf('@'));
5.153 - name = name.Trim();
5.154 -
5.155 - this.family = ((cpuidData[1, 0] & 0x0FF00000) >> 20) +
5.156 - ((cpuidData[1, 0] & 0x0F00) >> 8);
5.157 - this.model = ((cpuidData[1, 0] & 0x0F0000) >> 12) +
5.158 - ((cpuidData[1, 0] & 0xF0) >> 4);
5.159 - this.stepping = (cpuidData[1, 0] & 0x0F);
5.160 -
5.161 - switch (cpuVendor) {
5.162 - case "GenuineIntel":
5.163 - hardware.Add(new IntelCPU(name, family, model, stepping,
5.164 - cpuidData, cpuidExtData));
5.165 + switch (threads[0].Vendor) {
5.166 + case Vendor.Intel:
5.167 + hardware.Add(new IntelCPU(coreThreads));
5.168 break;
5.169 - case "AuthenticAMD":
5.170 - // check if processor supports a digital thermal sensor
5.171 - if (maxCPUID_EXT >= 7 && (cpuidExtData[7, 3] & 1) != 0) {
5.172 - switch (family) {
5.173 - case 0x0F:
5.174 - hardware.Add(new AMD0FCPU(name, family, model, stepping,
5.175 - cpuidData, cpuidExtData));
5.176 - break;
5.177 - case 0x10:
5.178 - hardware.Add(new AMD10CPU(name, family, model, stepping,
5.179 - cpuidData, cpuidExtData));
5.180 - break;
5.181 - default:
5.182 - break;
5.183 - }
5.184 - }
5.185 - break;
5.186 + case Vendor.AMD:
5.187 + switch (threads[0].Family) {
5.188 + case 0x0F:
5.189 + hardware.Add(new AMD0FCPU(coreThreads));
5.190 + break;
5.191 + case 0x10:
5.192 + hardware.Add(new AMD10CPU(coreThreads));
5.193 + break;
5.194 + default:
5.195 + break;
5.196 + } break;
5.197 default:
5.198 break;
5.199 - }
5.200 + }
5.201 }
5.202 }
5.203 -
5.204 +
5.205 public IHardware[] Hardware {
5.206 get {
5.207 return hardware.ToArray();
5.208 @@ -178,32 +159,43 @@
5.209 public string GetReport() {
5.210
5.211 StringBuilder r = new StringBuilder();
5.212 -
5.213 +
5.214 r.AppendLine("CPUID");
5.215 r.AppendLine();
5.216 - r.AppendFormat("Processor Vendor: {0}{1}", cpuVendor,
5.217 - Environment.NewLine);
5.218 - r.AppendFormat("Processor Brand: {0}{1}", cpuBrandString,
5.219 - Environment.NewLine);
5.220 - r.AppendFormat("Family: 0x{0}{1}", family.ToString("X"),
5.221 - Environment.NewLine);
5.222 - r.AppendFormat("Model: 0x{0}{1}", model.ToString("X"),
5.223 - Environment.NewLine);
5.224 - r.AppendFormat("Stepping: 0x{0}{1}", stepping.ToString("X"),
5.225 - Environment.NewLine);
5.226 - r.AppendLine();
5.227
5.228 - r.AppendLine("CPUID Return Values");
5.229 - r.AppendLine();
5.230 + for (int i = 0; i < threads.Length; i++) {
5.231
5.232 - if (cpuidData != null) {
5.233 - r.AppendLine(" Function EAX EBX ECX EDX");
5.234 - AppendCpuidData(r, cpuidData, CPUID);
5.235 - AppendCpuidData(r, cpuidExtData, CPUID_EXT);
5.236 + r.AppendLine("Processor " + i);
5.237 r.AppendLine();
5.238 + r.AppendFormat("Processor Vendor: {0}{1}", threads[i][0][0].Vendor,
5.239 + Environment.NewLine);
5.240 + r.AppendFormat("Processor Brand: {0}{1}", threads[i][0][0].BrandString,
5.241 + Environment.NewLine);
5.242 + r.AppendFormat("Family: 0x{0}{1}",
5.243 + threads[i][0][0].Family.ToString("X"), Environment.NewLine);
5.244 + r.AppendFormat("Model: 0x{0}{1}",
5.245 + threads[i][0][0].Model.ToString("X"), Environment.NewLine);
5.246 + r.AppendFormat("Stepping: 0x{0}{1}",
5.247 + threads[i][0][0].Stepping.ToString("X"), Environment.NewLine);
5.248 + r.AppendLine();
5.249 +
5.250 + r.AppendLine("CPUID Return Values");
5.251 + r.AppendLine();
5.252 + for (int j = 0; j < threads[i].Length; j++)
5.253 + for (int k = 0; k < threads[i][j].Length; k++) {
5.254 + r.AppendLine(" CPU Thread: " + threads[i][j][k].Thread);
5.255 + r.AppendLine(" APIC ID: " + threads[i][j][k].ApicId);
5.256 + r.AppendLine(" Processor ID: " + threads[i][j][k].ProcessorId);
5.257 + r.AppendLine(" Core ID: " + threads[i][j][k].CoreId);
5.258 + r.AppendLine(" Thread ID: " + threads[i][j][k].ThreadId);
5.259 + r.AppendLine();
5.260 + r.AppendLine(" Function EAX EBX ECX EDX");
5.261 + AppendCpuidData(r, threads[i][j][k].Data, CPUID.CPUID_0);
5.262 + AppendCpuidData(r, threads[i][j][k].ExtData, CPUID.CPUID_EXT);
5.263 + r.AppendLine();
5.264 + }
5.265 }
5.266 -
5.267 - return r.ToString();
5.268 + return r.ToString();
5.269 }
5.270
5.271 public void Close() { }
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/Hardware/CPU/CPUID.cs Sat Apr 24 19:59:52 2010 +0000
6.3 @@ -0,0 +1,252 @@
6.4 +/*
6.5 +
6.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
6.7 +
6.8 + The contents of this file are subject to the Mozilla Public License Version
6.9 + 1.1 (the "License"); you may not use this file except in compliance with
6.10 + the License. You may obtain a copy of the License at
6.11 +
6.12 + http://www.mozilla.org/MPL/
6.13 +
6.14 + Software distributed under the License is distributed on an "AS IS" basis,
6.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
6.16 + for the specific language governing rights and limitations under the License.
6.17 +
6.18 + The Original Code is the Open Hardware Monitor code.
6.19 +
6.20 + The Initial Developer of the Original Code is
6.21 + Michael Möller <m.moeller@gmx.ch>.
6.22 + Portions created by the Initial Developer are Copyright (C) 2009-2010
6.23 + the Initial Developer. All Rights Reserved.
6.24 +
6.25 + Contributor(s):
6.26 +
6.27 + Alternatively, the contents of this file may be used under the terms of
6.28 + either the GNU General Public License Version 2 or later (the "GPL"), or
6.29 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
6.30 + in which case the provisions of the GPL or the LGPL are applicable instead
6.31 + of those above. If you wish to allow use of your version of this file only
6.32 + under the terms of either the GPL or the LGPL, and not to allow others to
6.33 + use your version of this file under the terms of the MPL, indicate your
6.34 + decision by deleting the provisions above and replace them with the notice
6.35 + and other provisions required by the GPL or the LGPL. If you do not delete
6.36 + the provisions above, a recipient may use your version of this file under
6.37 + the terms of any one of the MPL, the GPL or the LGPL.
6.38 +
6.39 +*/
6.40 +
6.41 +using System;
6.42 +using System.Collections.Generic;
6.43 +using System.Text;
6.44 +
6.45 +namespace OpenHardwareMonitor.Hardware.CPU {
6.46 +
6.47 + public enum Vendor {
6.48 + Unknown,
6.49 + Intel,
6.50 + AMD,
6.51 + }
6.52 +
6.53 + public class CPUID {
6.54 +
6.55 + private int thread;
6.56 +
6.57 + private uint maxCpuid = 0;
6.58 + private uint maxCpuidExt = 0;
6.59 +
6.60 + private Vendor vendor;
6.61 +
6.62 + private string cpuBrandString;
6.63 + private string name;
6.64 +
6.65 + private uint[,] cpuidData;
6.66 + private uint[,] cpuidExtData;
6.67 +
6.68 + private uint family;
6.69 + private uint model;
6.70 + private uint stepping;
6.71 +
6.72 + private uint apicId;
6.73 +
6.74 + private uint threadMaskWith;
6.75 + private uint coreMaskWith;
6.76 +
6.77 + private uint processorId;
6.78 + private uint coreId;
6.79 + private uint threadId;
6.80 +
6.81 + public static uint CPUID_0 = 0;
6.82 + public static uint CPUID_EXT = 0x80000000;
6.83 +
6.84 + private void AppendRegister(StringBuilder b, uint value) {
6.85 + b.Append((char)((value) & 0xff));
6.86 + b.Append((char)((value >> 8) & 0xff));
6.87 + b.Append((char)((value >> 16) & 0xff));
6.88 + b.Append((char)((value >> 24) & 0xff));
6.89 + }
6.90 +
6.91 + public CPUID(int thread) {
6.92 + this.thread = thread;
6.93 +
6.94 + uint eax, ebx, ecx, edx;
6.95 +
6.96 + UIntPtr mask = (UIntPtr)(1L << thread);
6.97 +
6.98 + if (WinRing0.CpuidTx(CPUID_0, 0,
6.99 + out eax, out ebx, out ecx, out edx, mask)) {
6.100 + maxCpuid = eax;
6.101 + StringBuilder vendorBuilder = new StringBuilder();
6.102 + AppendRegister(vendorBuilder, ebx);
6.103 + AppendRegister(vendorBuilder, edx);
6.104 + AppendRegister(vendorBuilder, ecx);
6.105 + string cpuVendor = vendorBuilder.ToString();
6.106 + switch (cpuVendor) {
6.107 + case "GenuineIntel":
6.108 + vendor = Vendor.Intel;
6.109 + break;
6.110 + case "AuthenticAMD":
6.111 + vendor = Vendor.AMD;
6.112 + break;
6.113 + default:
6.114 + vendor = Vendor.Unknown;
6.115 + break;
6.116 + }
6.117 + eax = ebx = ecx = edx = 0;
6.118 + if (WinRing0.CpuidTx(CPUID_EXT, 0,
6.119 + out eax, out ebx, out ecx, out edx, mask))
6.120 + maxCpuidExt = eax - CPUID_EXT;
6.121 + } else {
6.122 + throw new ArgumentException();
6.123 + }
6.124 +
6.125 + if (maxCpuid == 0 || maxCpuidExt == 0)
6.126 + return;
6.127 +
6.128 + cpuidData = new uint[maxCpuid + 1, 4];
6.129 + for (uint i = 0; i < (maxCpuid + 1); i++)
6.130 + WinRing0.CpuidTx(CPUID_0 + i, 0,
6.131 + out cpuidData[i, 0], out cpuidData[i, 1],
6.132 + out cpuidData[i, 2], out cpuidData[i, 3], mask);
6.133 +
6.134 + cpuidExtData = new uint[MaxCpuidExt + 1, 4];
6.135 + for (uint i = 0; i < (MaxCpuidExt + 1); i++)
6.136 + WinRing0.CpuidTx(CPUID_EXT + i, 0,
6.137 + out cpuidExtData[i, 0], out cpuidExtData[i, 1],
6.138 + out cpuidExtData[i, 2], out cpuidExtData[i, 3], mask);
6.139 +
6.140 + StringBuilder nameBuilder = new StringBuilder();
6.141 + for (uint i = 2; i <= 4; i++) {
6.142 + if (WinRing0.CpuidTx(CPUID_EXT + i, 0,
6.143 + out eax, out ebx, out ecx, out edx, mask))
6.144 + {
6.145 + AppendRegister(nameBuilder, eax);
6.146 + AppendRegister(nameBuilder, ebx);
6.147 + AppendRegister(nameBuilder, ecx);
6.148 + AppendRegister(nameBuilder, edx);
6.149 + }
6.150 + }
6.151 + nameBuilder.Replace('\0', ' ');
6.152 + cpuBrandString = nameBuilder.ToString().Trim();
6.153 + nameBuilder.Replace("(R)", " ");
6.154 + nameBuilder.Replace("(TM)", " ");
6.155 + nameBuilder.Replace("(tm)", " ");
6.156 + nameBuilder.Replace("CPU", "");
6.157 + for (int i = 0; i < 10; i++) nameBuilder.Replace(" ", " ");
6.158 + name = nameBuilder.ToString();
6.159 + if (name.Contains("@"))
6.160 + name = name.Remove(name.LastIndexOf('@'));
6.161 + name = name.Trim();
6.162 +
6.163 + this.family = ((cpuidData[1, 0] & 0x0FF00000) >> 20) +
6.164 + ((cpuidData[1, 0] & 0x0F00) >> 8);
6.165 + this.model = ((cpuidData[1, 0] & 0x0F0000) >> 12) +
6.166 + ((cpuidData[1, 0] & 0xF0) >> 4);
6.167 + this.stepping = (cpuidData[1, 0] & 0x0F);
6.168 +
6.169 + this.apicId = (cpuidData[1, 1] >> 24) & 0xFF;
6.170 +
6.171 + switch (vendor) {
6.172 + case Vendor.Intel:
6.173 + uint maxCoreAndThreadIdPerPackage = (cpuidData[1, 1] >> 16) & 0xFF;
6.174 + uint maxCoreIdPerPackage = ((cpuidData[4, 0] >> 26) & 0x3F) + 1;
6.175 + threadMaskWith = (uint)Math.Ceiling(Math.Log(
6.176 + maxCoreAndThreadIdPerPackage / maxCoreIdPerPackage, 2));
6.177 + coreMaskWith = (uint)Math.Ceiling(Math.Log(maxCoreIdPerPackage, 2));
6.178 + break;
6.179 + case Vendor.AMD:
6.180 + uint corePerPackage = (cpuidExtData[8, 2] & 0xFF) + 1;
6.181 + threadMaskWith = 0;
6.182 + coreMaskWith = (uint)Math.Ceiling(Math.Log(corePerPackage, 2));
6.183 + break;
6.184 + default:
6.185 + threadMaskWith = 0;
6.186 + coreMaskWith = 0;
6.187 + break;
6.188 + }
6.189 +
6.190 + processorId = (uint)(apicId >> (int)(coreMaskWith + threadMaskWith));
6.191 + coreId = (uint)((apicId >> (int)(threadMaskWith)) - processorId);
6.192 + threadId = apicId - processorId - coreId;
6.193 + }
6.194 +
6.195 + public string Name {
6.196 + get { return name; }
6.197 + }
6.198 +
6.199 + public string BrandString {
6.200 + get { return cpuBrandString; }
6.201 + }
6.202 +
6.203 + public int Thread {
6.204 + get { return thread; }
6.205 + }
6.206 +
6.207 + public uint MaxCPUID {
6.208 + get { return maxCpuid; }
6.209 + }
6.210 +
6.211 + public uint MaxCpuidExt {
6.212 + get { return maxCpuidExt; }
6.213 + }
6.214 +
6.215 + public Vendor Vendor {
6.216 + get { return vendor; }
6.217 + }
6.218 +
6.219 + public uint Family {
6.220 + get { return family; }
6.221 + }
6.222 +
6.223 + public uint Model {
6.224 + get { return model; }
6.225 + }
6.226 +
6.227 + public uint Stepping {
6.228 + get { return stepping; }
6.229 + }
6.230 +
6.231 + public uint ApicId {
6.232 + get { return apicId; }
6.233 + }
6.234 +
6.235 + public uint ProcessorId {
6.236 + get { return processorId; }
6.237 + }
6.238 +
6.239 + public uint CoreId {
6.240 + get { return coreId; }
6.241 + }
6.242 +
6.243 + public uint ThreadId {
6.244 + get { return threadId; }
6.245 + }
6.246 +
6.247 + public uint[,] Data {
6.248 + get { return cpuidData; }
6.249 + }
6.250 +
6.251 + public uint[,] ExtData {
6.252 + get { return cpuidExtData; }
6.253 + }
6.254 + }
6.255 +}
7.1 --- a/Hardware/CPU/CPULoad.cs Mon Apr 05 21:31:21 2010 +0000
7.2 +++ b/Hardware/CPU/CPULoad.cs Sat Apr 24 19:59:52 2010 +0000
7.3 @@ -68,8 +68,7 @@
7.4 [Out] SystemProcessorPerformanceInformation[] informations,
7.5 int structSize, out IntPtr returnLength);
7.6
7.7 - private uint coreCount;
7.8 - private uint logicalProcessorsPerCore;
7.9 + private CPUID[][] cpuid;
7.10
7.11 private long systemTime;
7.12 private long[] idleTimes;
7.13 @@ -80,7 +79,7 @@
7.14 private bool available = false;
7.15
7.16 private long[] GetIdleTimes() {
7.17 - long[] result = new long[coreCount * logicalProcessorsPerCore];
7.18 + long[] result = new long[cpuid.Length * cpuid[0].Length];
7.19 SystemProcessorPerformanceInformation[] informations = new
7.20 SystemProcessorPerformanceInformation[result.Length];
7.21
7.22 @@ -97,10 +96,9 @@
7.23 return result;
7.24 }
7.25
7.26 - public CPULoad(uint coreCount, uint logicalProcessorsPerCore) {
7.27 - this.coreCount = coreCount;
7.28 - this.logicalProcessorsPerCore = logicalProcessorsPerCore;
7.29 - this.coreLoads = new float[coreCount];
7.30 + public CPULoad(CPUID[][] cpuid) {
7.31 + this.cpuid = cpuid;
7.32 + this.coreLoads = new float[cpuid.Length];
7.33 this.systemTime = DateTime.Now.Ticks;
7.34 this.totalLoad = 0;
7.35 try {
7.36 @@ -135,21 +133,22 @@
7.37 return;
7.38
7.39 float total = 0;
7.40 - for (int i = 0; i < coreCount; i++) {
7.41 + int count = 0;
7.42 + for (int i = 0; i < cpuid.Length; i++) {
7.43 float value = 0;
7.44 - for (int j = 0; j < logicalProcessorsPerCore; j++) {
7.45 - long index = i * logicalProcessorsPerCore + j;
7.46 + for (int j = 0; j < cpuid[i].Length; j++) {
7.47 + long index = cpuid[i][j].Thread;
7.48 long delta = idleTimes[index] - this.idleTimes[index];
7.49 value += delta;
7.50 total += delta;
7.51 + count++;
7.52 }
7.53 - value = 1.0f - value / (logicalProcessorsPerCore *
7.54 + value = 1.0f - value / (cpuid[i].Length *
7.55 (systemTime - this.systemTime));
7.56 value = value < 0 ? 0 : value;
7.57 coreLoads[i] = value * 100;
7.58 }
7.59 - total = 1.0f - total / (coreCount * logicalProcessorsPerCore *
7.60 - (systemTime - this.systemTime));
7.61 + total = 1.0f - total / (count * (systemTime - this.systemTime));
7.62 total = total < 0 ? 0 : total;
7.63 this.totalLoad = total * 100;
7.64
8.1 --- a/Hardware/CPU/IntelCPU.cs Mon Apr 05 21:31:21 2010 +0000
8.2 +++ b/Hardware/CPU/IntelCPU.cs Sat Apr 24 19:59:52 2010 +0000
8.3 @@ -48,6 +48,9 @@
8.4 namespace OpenHardwareMonitor.Hardware.CPU {
8.5 public class IntelCPU : Hardware, IHardware {
8.6
8.7 + private CPUID[][] cpuid;
8.8 + private int coreCount;
8.9 +
8.10 private string name;
8.11 private Image icon;
8.12
8.13 @@ -60,15 +63,11 @@
8.14 private Sensor totalLoad;
8.15 private Sensor[] coreLoads;
8.16 private Sensor[] coreClocks;
8.17 - private Sensor busClock;
8.18 - private uint logicalProcessors;
8.19 - private uint logicalProcessorsPerCore;
8.20 - private uint coreCount;
8.21 + private Sensor busClock;
8.22 private bool hasTSC;
8.23 private bool invariantTSC;
8.24 private double estimatedMaxClock;
8.25
8.26 - private ulong affinityMask;
8.27 private CPULoad cpuLoad;
8.28
8.29 private ulong lastTimeStampCount;
8.30 @@ -87,10 +86,6 @@
8.31 return "CPU Core #" + (i + 1);
8.32 }
8.33
8.34 - [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
8.35 - private static extern bool GetProcessAffinityMask(IntPtr handle,
8.36 - out IntPtr processMask, out IntPtr systemMask);
8.37 -
8.38 private float[] Floats(float f) {
8.39 float[] result = new float[coreCount];
8.40 for (int i = 0; i < coreCount; i++)
8.41 @@ -98,64 +93,16 @@
8.42 return result;
8.43 }
8.44
8.45 - public IntelCPU(string name, uint family, uint model, uint stepping,
8.46 - uint[,] cpuidData, uint[,] cpuidExtData) {
8.47 -
8.48 - this.name = name;
8.49 + public IntelCPU(CPUID[][] cpuid) {
8.50 +
8.51 + this.cpuid = cpuid;
8.52 + this.coreCount = cpuid.Length;
8.53 + this.name = cpuid[0][0].Name;
8.54 this.icon = Utilities.EmbeddedResources.GetImage("cpu.png");
8.55
8.56 - this.family = family;
8.57 - this.model = model;
8.58 - this.stepping = stepping;
8.59 -
8.60 - logicalProcessors = 0;
8.61 - if (cpuidData.GetLength(0) > 0x0B) {
8.62 - uint eax, ebx, ecx, edx;
8.63 - WinRing0.CpuidEx(0x0B, 0, out eax, out ebx, out ecx, out edx);
8.64 - logicalProcessorsPerCore = ebx & 0xFF;
8.65 - if (logicalProcessorsPerCore > 0) {
8.66 - WinRing0.CpuidEx(0x0B, 1, out eax, out ebx, out ecx, out edx);
8.67 - logicalProcessors = ebx & 0xFF;
8.68 - }
8.69 - }
8.70 - if (logicalProcessors <= 0 && cpuidData.GetLength(0) > 0x04) {
8.71 - uint coresPerPackage = ((cpuidData[4, 0] >> 26) & 0x3F) + 1;
8.72 - uint logicalPerPackage = (cpuidData[1, 1] >> 16) & 0xFF;
8.73 - logicalProcessorsPerCore = logicalPerPackage / coresPerPackage;
8.74 - logicalProcessors = logicalPerPackage;
8.75 - }
8.76 - if (logicalProcessors <= 0 && cpuidData.GetLength(0) > 0x01) {
8.77 - uint logicalPerPackage = (cpuidData[1, 1] >> 16) & 0xFF;
8.78 - logicalProcessorsPerCore = logicalPerPackage;
8.79 - logicalProcessors = logicalPerPackage;
8.80 - }
8.81 - if (logicalProcessors <= 0) {
8.82 - logicalProcessors = 1;
8.83 - logicalProcessorsPerCore = 1;
8.84 - }
8.85 -
8.86 - IntPtr processMask, systemMask;
8.87 - GetProcessAffinityMask(Process.GetCurrentProcess().Handle,
8.88 - out processMask, out systemMask);
8.89 - affinityMask = (ulong)systemMask;
8.90 -
8.91 - // correct values in case HypeThreading is disabled
8.92 - if (logicalProcessorsPerCore > 1) {
8.93 - ulong affinity = affinityMask;
8.94 - int availableLogicalProcessors = 0;
8.95 - while (affinity != 0) {
8.96 - if ((affinity & 0x1) > 0)
8.97 - availableLogicalProcessors++;
8.98 - affinity >>= 1;
8.99 - }
8.100 - while (logicalProcessorsPerCore > 1 &&
8.101 - availableLogicalProcessors < logicalProcessors) {
8.102 - logicalProcessors >>= 1;
8.103 - logicalProcessorsPerCore >>= 1;
8.104 - }
8.105 - }
8.106 -
8.107 - coreCount = logicalProcessors / logicalProcessorsPerCore;
8.108 + this.family = cpuid[0][0].Family;
8.109 + this.model = cpuid[0][0].Model;
8.110 + this.stepping = cpuid[0][0].Stepping;
8.111
8.112 float[] tjMax;
8.113 switch (family) {
8.114 @@ -191,8 +138,7 @@
8.115 tjMax = new float[coreCount];
8.116 for (int i = 0; i < coreCount; i++) {
8.117 if (WinRing0.RdmsrTx(IA32_TEMPERATURE_TARGET, out eax,
8.118 - out edx, (UIntPtr)(
8.119 - 1 << (int)(logicalProcessorsPerCore * i))))
8.120 + out edx, (UIntPtr)(1L << cpuid[i][0].Thread)))
8.121 {
8.122 tjMax[i] = (eax >> 16) & 0xFF;
8.123 } else {
8.124 @@ -211,7 +157,9 @@
8.125 }
8.126
8.127 // check if processor supports a digital thermal sensor
8.128 - if (cpuidData.GetLength(0) > 6 && (cpuidData[6, 0] & 1) != 0) {
8.129 + if (cpuid[0][0].Data.GetLength(0) > 6 &&
8.130 + (cpuid[0][0].Data[6, 0] & 1) != 0)
8.131 + {
8.132 coreTemperatures = new Sensor[coreCount];
8.133 for (int i = 0; i < coreTemperatures.Length; i++) {
8.134 coreTemperatures[i] = new Sensor(CoreString(i), i, tjMax[i],
8.135 @@ -235,7 +183,7 @@
8.136 for (int i = 0; i < coreLoads.Length; i++)
8.137 coreLoads[i] = new Sensor(CoreString(i), i + 1,
8.138 SensorType.Load, this);
8.139 - cpuLoad = new CPULoad(coreCount, logicalProcessorsPerCore);
8.140 + cpuLoad = new CPULoad(cpuid);
8.141 if (cpuLoad.IsAvailable) {
8.142 foreach (Sensor sensor in coreLoads)
8.143 ActivateSensor(sensor);
8.144 @@ -244,13 +192,15 @@
8.145 }
8.146
8.147 // check if processor has TSC
8.148 - if (cpuidData.GetLength(0) > 1 && (cpuidData[1, 3] & 0x10) != 0)
8.149 + if (cpuid[0][0].Data.GetLength(0) > 1
8.150 + && (cpuid[0][0].Data[1, 3] & 0x10) != 0)
8.151 hasTSC = true;
8.152 else
8.153 hasTSC = false;
8.154
8.155 // check if processor supports invariant TSC
8.156 - if (cpuidExtData.GetLength(0) > 7 && (cpuidExtData[7, 3] & 0x100) != 0)
8.157 + if (cpuid[0][0].ExtData.GetLength(0) > 7
8.158 + && (cpuid[0][0].ExtData[7, 3] & 0x100) != 0)
8.159 invariantTSC = true;
8.160 else
8.161 invariantTSC = false;
8.162 @@ -288,10 +238,9 @@
8.163 get { return icon; }
8.164 }
8.165
8.166 - private void AppendMSRData(StringBuilder r, uint msr, int core) {
8.167 + private void AppendMSRData(StringBuilder r, uint msr, int thread) {
8.168 uint eax, edx;
8.169 - if (WinRing0.RdmsrTx(msr, out eax, out edx,
8.170 - (UIntPtr)(1 << (int)(logicalProcessorsPerCore * core)))) {
8.171 + if (WinRing0.RdmsrTx(msr, out eax, out edx, (UIntPtr)(1L << thread))) {
8.172 r.Append(" ");
8.173 r.Append((msr).ToString("X8"));
8.174 r.Append(" ");
8.175 @@ -310,10 +259,8 @@
8.176 r.AppendFormat("Name: {0}{1}", name, Environment.NewLine);
8.177 r.AppendFormat("Number of Cores: {0}{1}", coreCount,
8.178 Environment.NewLine);
8.179 - r.AppendFormat("Threads per Core: {0}{1}", logicalProcessorsPerCore,
8.180 - Environment.NewLine);
8.181 - r.AppendFormat("Affinity Mask: 0x{0}{1}", affinityMask.ToString("X"),
8.182 - Environment.NewLine);
8.183 + r.AppendFormat("Threads per Core: {0}{1}", cpuid[0].Length,
8.184 + Environment.NewLine);
8.185 r.AppendLine("TSC: " +
8.186 (hasTSC ? (invariantTSC ? "Invariant" : "Not Invariant") : "None"));
8.187 r.AppendLine(string.Format(CultureInfo.InvariantCulture,
8.188 @@ -322,14 +269,14 @@
8.189 "Max Clock: {0} MHz", Math.Round(estimatedMaxClock * 100) * 0.01));
8.190 r.AppendLine();
8.191
8.192 - for (int i = 0; i < coreCount; i++) {
8.193 + for (int i = 0; i < cpuid.Length; i++) {
8.194 r.AppendLine("MSR Core #" + (i + 1));
8.195 r.AppendLine();
8.196 r.AppendLine(" MSR EDX EAX");
8.197 - AppendMSRData(r, MSR_PLATFORM_INFO, i);
8.198 - AppendMSRData(r, IA32_PERF_STATUS, i);
8.199 - AppendMSRData(r, IA32_THERM_STATUS_MSR, i);
8.200 - AppendMSRData(r, IA32_TEMPERATURE_TARGET, i);
8.201 + AppendMSRData(r, MSR_PLATFORM_INFO, cpuid[i][0].Thread);
8.202 + AppendMSRData(r, IA32_PERF_STATUS, cpuid[i][0].Thread);
8.203 + AppendMSRData(r, IA32_THERM_STATUS_MSR, cpuid[i][0].Thread);
8.204 + AppendMSRData(r, IA32_TEMPERATURE_TARGET, cpuid[i][0].Thread);
8.205 r.AppendLine();
8.206 }
8.207
8.208 @@ -360,8 +307,8 @@
8.209 for (int i = 0; i < coreTemperatures.Length; i++) {
8.210 uint eax, edx;
8.211 if (WinRing0.RdmsrTx(
8.212 - IA32_THERM_STATUS_MSR, out eax, out edx,
8.213 - (UIntPtr)(1 << (int)(logicalProcessorsPerCore * i)))) {
8.214 + IA32_THERM_STATUS_MSR, out eax, out edx,
8.215 + (UIntPtr)(1L << cpuid[i][0].Thread))) {
8.216 // if reading is valid
8.217 if ((eax & 0x80000000) != 0) {
8.218 // get the dist from tjMax from bits 22:16
8.219 @@ -402,7 +349,7 @@
8.220 for (int i = 0; i < coreClocks.Length; i++) {
8.221 System.Threading.Thread.Sleep(1);
8.222 if (WinRing0.RdmsrTx(IA32_PERF_STATUS, out eax, out edx,
8.223 - (UIntPtr)(1 << (int)(logicalProcessorsPerCore * i)))) {
8.224 + (UIntPtr)(1L << cpuid[i][0].Thread))) {
8.225 if (maxNehalemMultiplier > 0) { // Core i3, i5, i7
8.226 uint nehalemMultiplier = eax & 0xff;
8.227 coreClocks[i].Value =
9.1 --- a/Hardware/WinRing0.cs Mon Apr 05 21:31:21 2010 +0000
9.2 +++ b/Hardware/WinRing0.cs Sat Apr 24 19:59:52 2010 +0000
9.3 @@ -79,10 +79,11 @@
9.4
9.5 public delegate uint GetDllStatusDelegate();
9.6 public delegate bool IsCpuidDelegate();
9.7 - public delegate bool CpuidDelegate(uint index,
9.8 + public delegate bool CpuidDelegate(uint index, uint ecxValue,
9.9 out uint eax, out uint ebx, out uint ecx, out uint edx);
9.10 - public delegate bool CpuidExDelegate(uint index, uint ecxValue,
9.11 - out uint eax, out uint ebx, out uint ecx, out uint edx);
9.12 + public delegate bool CpuidTxDelegate(uint index, uint ecxValue,
9.13 + out uint eax, out uint ebx, out uint ecx, out uint edx,
9.14 + UIntPtr threadAffinityMask);
9.15 public delegate bool RdmsrDelegate(uint index, out uint eax, out uint edx);
9.16 public delegate bool RdmsrTxDelegate(uint index, out uint eax, out uint edx,
9.17 UIntPtr threadAffinityMask);
9.18 @@ -105,7 +106,7 @@
9.19 public static GetDllStatusDelegate GetDllStatus;
9.20 public static IsCpuidDelegate IsCpuid;
9.21 public static CpuidDelegate Cpuid;
9.22 - public static CpuidExDelegate CpuidEx;
9.23 + public static CpuidTxDelegate CpuidTx;
9.24 public static RdmsrDelegate Rdmsr;
9.25 public static RdmsrTxDelegate RdmsrTx;
9.26 public static ReadIoPortByteDelegate ReadIoPortByte;
9.27 @@ -134,7 +135,7 @@
9.28 GetDelegate("GetDllStatus", out GetDllStatus);
9.29 GetDelegate("IsCpuid", out IsCpuid);
9.30 GetDelegate("Cpuid", out Cpuid);
9.31 - GetDelegate("CpuidEx", out CpuidEx);
9.32 + GetDelegate("CpuidTx", out CpuidTx);
9.33 GetDelegate("Rdmsr", out Rdmsr);
9.34 GetDelegate("RdmsrTx", out RdmsrTx);
9.35 GetDelegate("ReadIoPortByte", out ReadIoPortByte);
10.1 --- a/OpenHardwareMonitor.csproj Mon Apr 05 21:31:21 2010 +0000
10.2 +++ b/OpenHardwareMonitor.csproj Sat Apr 24 19:59:52 2010 +0000
10.3 @@ -78,6 +78,7 @@
10.4 <Compile Include="GUI\TypeNode.cs" />
10.5 <Compile Include="Hardware\CPU\AMD10CPU.cs" />
10.6 <Compile Include="Hardware\CPU\AMD0FCPU.cs" />
10.7 + <Compile Include="Hardware\CPU\CPUID.cs" />
10.8 <Compile Include="Hardware\CPU\CPULoad.cs" />
10.9 <Compile Include="Hardware\Hardware.cs" />
10.10 <Compile Include="Hardware\HDD\HDD.cs" />