Implemented APIC based CPU enumeration (Issue 41).
authormoel.mich
Sat, 24 Apr 2010 19:59:52 +0000
changeset 903333b29a1746
parent 89 62e0b6011e8c
child 91 c0937b698b81
Implemented APIC based CPU enumeration (Issue 41).
External/WinRing0.dll
External/WinRing0x64.dll
Hardware/CPU/AMD0FCPU.cs
Hardware/CPU/AMD10CPU.cs
Hardware/CPU/CPUGroup.cs
Hardware/CPU/CPUID.cs
Hardware/CPU/CPULoad.cs
Hardware/CPU/IntelCPU.cs
Hardware/WinRing0.cs
OpenHardwareMonitor.csproj
     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" />