1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/Hardware/CPU/CPUGroup.cs Tue Jan 26 22:37:48 2010 +0000
1.3 @@ -0,0 +1,208 @@
1.4 +/*
1.5 +
1.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
1.7 +
1.8 + The contents of this file are subject to the Mozilla Public License Version
1.9 + 1.1 (the "License"); you may not use this file except in compliance with
1.10 + the License. You may obtain a copy of the License at
1.11 +
1.12 + http://www.mozilla.org/MPL/
1.13 +
1.14 + Software distributed under the License is distributed on an "AS IS" basis,
1.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
1.16 + for the specific language governing rights and limitations under the License.
1.17 +
1.18 + The Original Code is the Open Hardware Monitor code.
1.19 +
1.20 + The Initial Developer of the Original Code is
1.21 + Michael Möller <m.moeller@gmx.ch>.
1.22 + Portions created by the Initial Developer are Copyright (C) 2009-2010
1.23 + the Initial Developer. All Rights Reserved.
1.24 +
1.25 + Contributor(s):
1.26 +
1.27 + Alternatively, the contents of this file may be used under the terms of
1.28 + either the GNU General Public License Version 2 or later (the "GPL"), or
1.29 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
1.30 + in which case the provisions of the GPL or the LGPL are applicable instead
1.31 + of those above. If you wish to allow use of your version of this file only
1.32 + under the terms of either the GPL or the LGPL, and not to allow others to
1.33 + use your version of this file under the terms of the MPL, indicate your
1.34 + decision by deleting the provisions above and replace them with the notice
1.35 + and other provisions required by the GPL or the LGPL. If you do not delete
1.36 + the provisions above, a recipient may use your version of this file under
1.37 + the terms of any one of the MPL, the GPL or the LGPL.
1.38 +
1.39 +*/
1.40 +
1.41 +using System;
1.42 +using System.Collections.Generic;
1.43 +using System.Text;
1.44 +
1.45 +namespace OpenHardwareMonitor.Hardware.CPU {
1.46 +
1.47 + public class CPUGroup : IGroup {
1.48 + private List<IHardware> hardware = new List<IHardware>();
1.49 +
1.50 + private string cpuBrandString;
1.51 + private string cpuVendor;
1.52 + private uint[,] cpuidData;
1.53 + private uint[,] cpuidExtData;
1.54 +
1.55 + private uint family;
1.56 + private uint model;
1.57 + private uint stepping;
1.58 +
1.59 + private static uint CPUID = 0;
1.60 + private static uint CPUID_EXT = 0x80000000;
1.61 +
1.62 + public static void AppendRegister(StringBuilder b, uint value) {
1.63 + b.Append((char)((value) & 0xff));
1.64 + b.Append((char)((value >> 8) & 0xff));
1.65 + b.Append((char)((value >> 16) & 0xff));
1.66 + b.Append((char)((value >> 24) & 0xff));
1.67 + }
1.68 +
1.69 + public CPUGroup() {
1.70 +
1.71 + if (!WinRing0.IsAvailable)
1.72 + return;
1.73 +
1.74 + if (WinRing0.IsCpuid()) {
1.75 + uint maxCPUID = 0;
1.76 + uint maxCPUID_EXT = 0;
1.77 + uint eax, ebx, ecx, edx;
1.78 +
1.79 +
1.80 + if (WinRing0.Cpuid(CPUID, out eax, out ebx, out ecx, out edx)) {
1.81 + maxCPUID = eax;
1.82 + StringBuilder vendorBuilder = new StringBuilder();
1.83 + AppendRegister(vendorBuilder, ebx);
1.84 + AppendRegister(vendorBuilder, edx);
1.85 + AppendRegister(vendorBuilder, ecx);
1.86 + cpuVendor = vendorBuilder.ToString();
1.87 +
1.88 + eax = ebx = ecx = edx = 0;
1.89 + if (WinRing0.Cpuid(CPUID_EXT, out eax, out ebx, out ecx, out edx)) {
1.90 + maxCPUID_EXT = eax - CPUID_EXT;
1.91 + }
1.92 + }
1.93 + if (maxCPUID == 0 || maxCPUID_EXT == 0)
1.94 + return;
1.95 +
1.96 + cpuidData = new uint[maxCPUID + 1, 4];
1.97 + for (uint i = 0; i < (maxCPUID + 1); i++)
1.98 + WinRing0.Cpuid(CPUID + i, out cpuidData[i, 0], out cpuidData[i, 1],
1.99 + out cpuidData[i, 2], out cpuidData[i, 3]);
1.100 +
1.101 + cpuidExtData = new uint[maxCPUID_EXT + 1, 4];
1.102 + for (uint i = 0; i < (maxCPUID_EXT + 1); i++)
1.103 + WinRing0.Cpuid(CPUID_EXT + i, out cpuidExtData[i, 0],
1.104 + out cpuidExtData[i, 1], out cpuidExtData[i, 2],
1.105 + out cpuidExtData[i, 3]);
1.106 +
1.107 + StringBuilder nameBuilder = new StringBuilder();
1.108 + for (uint i = 2; i <= 4; i++) {
1.109 + if (WinRing0.Cpuid(CPUID_EXT + i, out eax, out ebx, out ecx, out edx))
1.110 + {
1.111 + AppendRegister(nameBuilder, eax);
1.112 + AppendRegister(nameBuilder, ebx);
1.113 + AppendRegister(nameBuilder, ecx);
1.114 + AppendRegister(nameBuilder, edx);
1.115 + }
1.116 + }
1.117 + cpuBrandString = nameBuilder.ToString();
1.118 + nameBuilder.Replace("(R)", " ");
1.119 + nameBuilder.Replace("(TM)", " ");
1.120 + nameBuilder.Replace("(tm)", " ");
1.121 + nameBuilder.Replace("CPU", "");
1.122 + for (int i = 0; i < 10; i++) nameBuilder.Replace(" ", " ");
1.123 + string name = nameBuilder.ToString();
1.124 + if (name.Contains("@"))
1.125 + name = name.Remove(name.LastIndexOf('@'));
1.126 + name = name.Trim();
1.127 +
1.128 + this.family = ((cpuidData[1, 0] & 0x0FF00000) >> 20) +
1.129 + ((cpuidData[1, 0] & 0x0F00) >> 8);
1.130 + this.model = ((cpuidData[1, 0] & 0x0F0000) >> 12) +
1.131 + ((cpuidData[1, 0] & 0xF0) >> 4);
1.132 + this.stepping = (cpuidData[1, 0] & 0x0F);
1.133 +
1.134 + switch (cpuVendor) {
1.135 + case "GenuineIntel":
1.136 + // check if processor supports a digital thermal sensor
1.137 + if (maxCPUID >= 6 && (cpuidData[6, 0] & 1) != 0)
1.138 + hardware.Add(new IntelCPU(name, family, model, stepping,
1.139 + cpuidData, cpuidExtData));
1.140 + break;
1.141 + case "AuthenticAMD":
1.142 + // check if processor supports a digital thermal sensor
1.143 + if (maxCPUID_EXT >= 7 && (cpuidExtData[7, 3] & 1) != 0) {
1.144 + switch (family) {
1.145 + case 0x10:
1.146 + hardware.Add(new AMD10CPU(name, family, model, stepping,
1.147 + cpuidData, cpuidExtData));
1.148 + break;
1.149 + default:
1.150 + break;
1.151 + }
1.152 + }
1.153 + break;
1.154 + default:
1.155 + break;
1.156 + }
1.157 + }
1.158 + }
1.159 +
1.160 + public IHardware[] Hardware {
1.161 + get {
1.162 + return hardware.ToArray();
1.163 + }
1.164 + }
1.165 +
1.166 + private void AppendCpuidData(StringBuilder r, uint[,] data, uint offset) {
1.167 + for (int i = 0; i < data.GetLength(0); i++) {
1.168 + r.Append(" ");
1.169 + r.Append((i + offset).ToString("X8"));
1.170 + for (int j = 0; j < 4; j++) {
1.171 + r.Append(" ");
1.172 + r.Append(data[i, j].ToString("X8"));
1.173 + }
1.174 + r.AppendLine();
1.175 + }
1.176 + }
1.177 +
1.178 + public string GetReport() {
1.179 + if (hardware.Count == 0)
1.180 + return null;
1.181 +
1.182 + StringBuilder r = new StringBuilder();
1.183 +
1.184 + r.AppendLine("CPUID");
1.185 + r.AppendLine();
1.186 + r.AppendFormat("Processor Vendor: {0}{1}", cpuVendor,
1.187 + Environment.NewLine);
1.188 + r.AppendFormat("Processor Brand: {0}{1}", cpuBrandString,
1.189 + Environment.NewLine);
1.190 + r.AppendFormat("Family: 0x{0}{1}", family.ToString("X"),
1.191 + Environment.NewLine);
1.192 + r.AppendFormat("Model: 0x{0}{1}", model.ToString("X"),
1.193 + Environment.NewLine);
1.194 + r.AppendFormat("Stepping: 0x{0}{1}", stepping.ToString("X"),
1.195 + Environment.NewLine);
1.196 + r.AppendLine();
1.197 +
1.198 + r.AppendLine("CPUID Return Values");
1.199 + r.AppendLine();
1.200 +
1.201 + r.AppendLine(" Function EAX EBX ECX EDX");
1.202 + AppendCpuidData(r, cpuidData, CPUID);
1.203 + AppendCpuidData(r, cpuidExtData, CPUID_EXT);
1.204 + r.AppendLine();
1.205 +
1.206 + return r.ToString();
1.207 + }
1.208 +
1.209 + public void Close() { }
1.210 + }
1.211 +}