Updated the version.
3 This Source Code Form is subject to the terms of the Mozilla Public
4 License, v. 2.0. If a copy of the MPL was not distributed with this
5 file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 Copyright (C) 2009-2010 Michael Möller <mmoeller@openhardwaremonitor.org>
14 namespace OpenHardwareMonitor.Hardware.CPU {
16 internal enum Vendor {
22 internal class CPUID {
24 private readonly int thread;
26 private readonly Vendor vendor = Vendor.Unknown;
28 private readonly string cpuBrandString = "";
29 private readonly string name = "";
31 private readonly uint[,] cpuidData = new uint[0, 0];
32 private readonly uint[,] cpuidExtData = new uint[0, 0];
34 private readonly uint family;
35 private readonly uint model;
36 private readonly uint stepping;
38 private readonly uint apicId;
40 private readonly uint threadMaskWith;
41 private readonly uint coreMaskWith;
43 private readonly uint processorId;
44 private readonly uint coreId;
45 private readonly uint threadId;
47 public const uint CPUID_0 = 0;
48 public const uint CPUID_EXT = 0x80000000;
50 private static void AppendRegister(StringBuilder b, uint value) {
51 b.Append((char)((value) & 0xff));
52 b.Append((char)((value >> 8) & 0xff));
53 b.Append((char)((value >> 16) & 0xff));
54 b.Append((char)((value >> 24) & 0xff));
57 private static uint NextLog2(long x) {
71 public CPUID(int thread) {
77 uint eax, ebx, ecx, edx;
80 throw new ArgumentOutOfRangeException("thread");
81 ulong mask = 1UL << thread;
83 if (Opcode.CpuidTx(CPUID_0, 0,
84 out eax, out ebx, out ecx, out edx, mask)) {
90 StringBuilder vendorBuilder = new StringBuilder();
91 AppendRegister(vendorBuilder, ebx);
92 AppendRegister(vendorBuilder, edx);
93 AppendRegister(vendorBuilder, ecx);
94 string cpuVendor = vendorBuilder.ToString();
97 vendor = Vendor.Intel;
103 vendor = Vendor.Unknown;
106 eax = ebx = ecx = edx = 0;
107 if (Opcode.CpuidTx(CPUID_EXT, 0,
108 out eax, out ebx, out ecx, out edx, mask)) {
110 maxCpuidExt = eax - CPUID_EXT;
114 throw new ArgumentOutOfRangeException("thread");
117 throw new ArgumentOutOfRangeException("thread");
120 maxCpuid = Math.Min(maxCpuid, 1024);
121 maxCpuidExt = Math.Min(maxCpuidExt, 1024);
123 cpuidData = new uint[maxCpuid + 1, 4];
124 for (uint i = 0; i < (maxCpuid + 1); i++)
125 Opcode.CpuidTx(CPUID_0 + i, 0,
126 out cpuidData[i, 0], out cpuidData[i, 1],
127 out cpuidData[i, 2], out cpuidData[i, 3], mask);
129 cpuidExtData = new uint[maxCpuidExt + 1, 4];
130 for (uint i = 0; i < (maxCpuidExt + 1); i++)
131 Opcode.CpuidTx(CPUID_EXT + i, 0,
132 out cpuidExtData[i, 0], out cpuidExtData[i, 1],
133 out cpuidExtData[i, 2], out cpuidExtData[i, 3], mask);
135 StringBuilder nameBuilder = new StringBuilder();
136 for (uint i = 2; i <= 4; i++) {
137 if (Opcode.CpuidTx(CPUID_EXT + i, 0,
138 out eax, out ebx, out ecx, out edx, mask))
140 AppendRegister(nameBuilder, eax);
141 AppendRegister(nameBuilder, ebx);
142 AppendRegister(nameBuilder, ecx);
143 AppendRegister(nameBuilder, edx);
146 nameBuilder.Replace('\0', ' ');
147 cpuBrandString = nameBuilder.ToString().Trim();
148 nameBuilder.Replace("(R)", " ");
149 nameBuilder.Replace("(TM)", " ");
150 nameBuilder.Replace("(tm)", "");
151 nameBuilder.Replace("CPU", "");
152 nameBuilder.Replace("Quad-Core Processor", "");
153 nameBuilder.Replace("Six-Core Processor", "");
154 nameBuilder.Replace("Eight-Core Processor", "");
155 for (int i = 0; i < 10; i++) nameBuilder.Replace(" ", " ");
156 name = nameBuilder.ToString();
157 if (name.Contains("@"))
158 name = name.Remove(name.LastIndexOf('@'));
161 this.family = ((cpuidData[1, 0] & 0x0FF00000) >> 20) +
162 ((cpuidData[1, 0] & 0x0F00) >> 8);
163 this.model = ((cpuidData[1, 0] & 0x0F0000) >> 12) +
164 ((cpuidData[1, 0] & 0xF0) >> 4);
165 this.stepping = (cpuidData[1, 0] & 0x0F);
167 this.apicId = (cpuidData[1, 1] >> 24) & 0xFF;
171 uint maxCoreAndThreadIdPerPackage = (cpuidData[1, 1] >> 16) & 0xFF;
172 uint maxCoreIdPerPackage;
174 maxCoreIdPerPackage = ((cpuidData[4, 0] >> 26) & 0x3F) + 1;
176 maxCoreIdPerPackage = 1;
178 NextLog2(maxCoreAndThreadIdPerPackage / maxCoreIdPerPackage);
179 coreMaskWith = NextLog2(maxCoreIdPerPackage);
183 if (maxCpuidExt >= 8)
184 corePerPackage = (cpuidExtData[8, 2] & 0xFF) + 1;
188 coreMaskWith = NextLog2(corePerPackage);
196 processorId = (apicId >> (int)(coreMaskWith + threadMaskWith));
197 coreId = ((apicId >> (int)(threadMaskWith))
198 - (processorId << (int)(coreMaskWith)));
200 - (processorId << (int)(coreMaskWith + threadMaskWith))
201 - (coreId << (int)(threadMaskWith));
208 public string BrandString {
209 get { return cpuBrandString; }
213 get { return thread; }
216 public Vendor Vendor {
217 get { return vendor; }
221 get { return family; }
225 get { return model; }
228 public uint Stepping {
229 get { return stepping; }
233 get { return apicId; }
236 public uint ProcessorId {
237 get { return processorId; }
241 get { return coreId; }
244 public uint ThreadId {
245 get { return threadId; }
248 public uint[,] Data {
249 get { return cpuidData; }
252 public uint[,] ExtData {
253 get { return cpuidExtData; }