Hardware/CPU/CPUGroup.cs
author moel.mich
Fri, 12 Feb 2010 22:46:31 +0000
changeset 42 47385d4fc990
parent 35 2daf59392c88
child 44 c150de283ca0
permissions -rw-r--r--
Tray sensor display default color is black and color can be changed now. Fixed CPU load reading for AMD CPUs and added additional misc device for AMD core temperature reading.
moel@1
     1
/*
moel@1
     2
  
moel@1
     3
  Version: MPL 1.1/GPL 2.0/LGPL 2.1
moel@1
     4
moel@1
     5
  The contents of this file are subject to the Mozilla Public License Version
moel@1
     6
  1.1 (the "License"); you may not use this file except in compliance with
moel@1
     7
  the License. You may obtain a copy of the License at
moel@1
     8
 
moel@1
     9
  http://www.mozilla.org/MPL/
moel@1
    10
moel@1
    11
  Software distributed under the License is distributed on an "AS IS" basis,
moel@1
    12
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
moel@1
    13
  for the specific language governing rights and limitations under the License.
moel@1
    14
moel@1
    15
  The Original Code is the Open Hardware Monitor code.
moel@1
    16
moel@1
    17
  The Initial Developer of the Original Code is 
moel@1
    18
  Michael Möller <m.moeller@gmx.ch>.
moel@1
    19
  Portions created by the Initial Developer are Copyright (C) 2009-2010
moel@1
    20
  the Initial Developer. All Rights Reserved.
moel@1
    21
moel@1
    22
  Contributor(s):
moel@1
    23
moel@1
    24
  Alternatively, the contents of this file may be used under the terms of
moel@1
    25
  either the GNU General Public License Version 2 or later (the "GPL"), or
moel@1
    26
  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
moel@1
    27
  in which case the provisions of the GPL or the LGPL are applicable instead
moel@1
    28
  of those above. If you wish to allow use of your version of this file only
moel@1
    29
  under the terms of either the GPL or the LGPL, and not to allow others to
moel@1
    30
  use your version of this file under the terms of the MPL, indicate your
moel@1
    31
  decision by deleting the provisions above and replace them with the notice
moel@1
    32
  and other provisions required by the GPL or the LGPL. If you do not delete
moel@1
    33
  the provisions above, a recipient may use your version of this file under
moel@1
    34
  the terms of any one of the MPL, the GPL or the LGPL.
moel@1
    35
 
moel@1
    36
*/
moel@1
    37
moel@1
    38
using System;
moel@1
    39
using System.Collections.Generic;
moel@1
    40
using System.Text;
moel@1
    41
moel@1
    42
namespace OpenHardwareMonitor.Hardware.CPU {
moel@1
    43
moel@1
    44
  public class CPUGroup : IGroup { 
moel@1
    45
    private List<IHardware> hardware = new List<IHardware>();
moel@1
    46
moel@1
    47
    private string cpuBrandString;
moel@1
    48
    private string cpuVendor;
moel@1
    49
    private uint[,] cpuidData;
moel@1
    50
    private uint[,] cpuidExtData;
moel@1
    51
moel@1
    52
    private uint family;
moel@1
    53
    private uint model;
moel@1
    54
    private uint stepping;
moel@1
    55
moel@1
    56
    private static uint CPUID = 0;
moel@1
    57
    private static uint CPUID_EXT = 0x80000000;
moel@1
    58
moel@1
    59
    public static void AppendRegister(StringBuilder b, uint value) {
moel@1
    60
      b.Append((char)((value) & 0xff));
moel@1
    61
      b.Append((char)((value >> 8) & 0xff));
moel@1
    62
      b.Append((char)((value >> 16) & 0xff));
moel@1
    63
      b.Append((char)((value >> 24) & 0xff));
moel@1
    64
    }
moel@1
    65
moel@1
    66
    public CPUGroup() {
moel@1
    67
moel@1
    68
      if (!WinRing0.IsAvailable) 
moel@1
    69
        return;
moel@1
    70
moel@1
    71
      if (WinRing0.IsCpuid()) {
moel@1
    72
        uint maxCPUID = 0;
moel@1
    73
        uint maxCPUID_EXT = 0;
moel@1
    74
        uint eax, ebx, ecx, edx;
moel@1
    75
moel@1
    76
        
moel@1
    77
        if (WinRing0.Cpuid(CPUID, out eax, out ebx, out ecx, out edx)) {
moel@1
    78
          maxCPUID = eax;
moel@1
    79
          StringBuilder vendorBuilder = new StringBuilder();
moel@1
    80
          AppendRegister(vendorBuilder, ebx);
moel@1
    81
          AppendRegister(vendorBuilder, edx);
moel@1
    82
          AppendRegister(vendorBuilder, ecx);
moel@1
    83
          cpuVendor = vendorBuilder.ToString();
moel@1
    84
moel@1
    85
          eax = ebx = ecx = edx = 0;
moel@1
    86
          if (WinRing0.Cpuid(CPUID_EXT, out eax, out ebx, out ecx, out edx)) {
moel@1
    87
            maxCPUID_EXT = eax - CPUID_EXT;
moel@1
    88
          }
moel@1
    89
        }
moel@1
    90
        if (maxCPUID == 0 || maxCPUID_EXT == 0)
moel@1
    91
          return;        
moel@1
    92
moel@1
    93
        cpuidData = new uint[maxCPUID + 1, 4];
moel@1
    94
        for (uint i = 0; i < (maxCPUID + 1); i++)
moel@1
    95
          WinRing0.Cpuid(CPUID + i, out cpuidData[i, 0], out cpuidData[i, 1],
moel@1
    96
            out cpuidData[i, 2], out cpuidData[i, 3]);
moel@1
    97
moel@1
    98
        cpuidExtData = new uint[maxCPUID_EXT + 1, 4];
moel@1
    99
        for (uint i = 0; i < (maxCPUID_EXT + 1); i++)
moel@1
   100
          WinRing0.Cpuid(CPUID_EXT + i, out cpuidExtData[i, 0],
moel@1
   101
            out cpuidExtData[i, 1], out cpuidExtData[i, 2],
moel@1
   102
            out cpuidExtData[i, 3]);
moel@1
   103
moel@1
   104
        StringBuilder nameBuilder = new StringBuilder();
moel@1
   105
        for (uint i = 2; i <= 4; i++) {
moel@1
   106
          if (WinRing0.Cpuid(CPUID_EXT + i, out eax, out ebx, out ecx, out edx)) 
moel@1
   107
          {
moel@1
   108
            AppendRegister(nameBuilder, eax);
moel@1
   109
            AppendRegister(nameBuilder, ebx);
moel@1
   110
            AppendRegister(nameBuilder, ecx);
moel@1
   111
            AppendRegister(nameBuilder, edx);
moel@1
   112
          }
moel@1
   113
        }
moel@36
   114
        nameBuilder.Replace('\0', ' ');
moel@36
   115
        cpuBrandString = nameBuilder.ToString().Trim();
moel@1
   116
        nameBuilder.Replace("(R)", " ");
moel@1
   117
        nameBuilder.Replace("(TM)", " ");
moel@1
   118
        nameBuilder.Replace("(tm)", " ");
moel@1
   119
        nameBuilder.Replace("CPU", "");
moel@1
   120
        for (int i = 0; i < 10; i++) nameBuilder.Replace("  ", " ");
moel@1
   121
        string name = nameBuilder.ToString();
moel@1
   122
        if (name.Contains("@"))
moel@1
   123
          name = name.Remove(name.LastIndexOf('@')); 
moel@1
   124
        name = name.Trim();
moel@1
   125
moel@1
   126
        this.family = ((cpuidData[1, 0] & 0x0FF00000) >> 20) +
moel@1
   127
          ((cpuidData[1, 0] & 0x0F00) >> 8);
moel@1
   128
        this.model = ((cpuidData[1, 0] & 0x0F0000) >> 12) +
moel@1
   129
          ((cpuidData[1, 0] & 0xF0) >> 4);
moel@1
   130
        this.stepping = (cpuidData[1, 0] & 0x0F);
moel@1
   131
moel@1
   132
        switch (cpuVendor) {
moel@1
   133
          case "GenuineIntel":
moel@1
   134
            // check if processor supports a digital thermal sensor
moel@1
   135
            if (maxCPUID >= 6 && (cpuidData[6, 0] & 1) != 0) 
moel@1
   136
              hardware.Add(new IntelCPU(name, family, model, stepping, 
moel@1
   137
                cpuidData, cpuidExtData));
moel@1
   138
            break;
moel@1
   139
          case "AuthenticAMD":                       
moel@1
   140
            // check if processor supports a digital thermal sensor            
moel@1
   141
            if (maxCPUID_EXT >= 7 && (cpuidExtData[7, 3] & 1) != 0) {
moel@1
   142
              switch (family) {
moel@14
   143
                case 0x0F:
moel@14
   144
                  hardware.Add(new AMD0FCPU(name, family, model, stepping,
moel@14
   145
                    cpuidData, cpuidExtData));
moel@14
   146
                  break;
moel@1
   147
                case 0x10:
moel@1
   148
                  hardware.Add(new AMD10CPU(name, family, model, stepping,
moel@1
   149
                    cpuidData, cpuidExtData));
moel@1
   150
                  break;
moel@1
   151
                default:
moel@1
   152
                  break;
moel@1
   153
              }
moel@1
   154
            }
moel@1
   155
            break;
moel@1
   156
          default:
moel@1
   157
            break;
moel@1
   158
        }
moel@1
   159
      }
moel@1
   160
    }
moel@1
   161
moel@1
   162
    public IHardware[] Hardware {
moel@1
   163
      get {
moel@1
   164
        return hardware.ToArray();
moel@1
   165
      }
moel@1
   166
    }
moel@1
   167
moel@1
   168
    private void AppendCpuidData(StringBuilder r, uint[,] data, uint offset) {
moel@1
   169
      for (int i = 0; i < data.GetLength(0); i++) {
moel@1
   170
        r.Append(" ");
moel@1
   171
        r.Append((i + offset).ToString("X8"));
moel@1
   172
        for (int j = 0; j < 4; j++) {
moel@1
   173
          r.Append("  ");
moel@1
   174
          r.Append(data[i, j].ToString("X8"));
moel@1
   175
        }
moel@1
   176
        r.AppendLine();
moel@1
   177
      }
moel@1
   178
    }
moel@1
   179
moel@1
   180
    public string GetReport() {
moel@1
   181
moel@1
   182
      StringBuilder r = new StringBuilder();
moel@1
   183
moel@1
   184
      r.AppendLine("CPUID");
moel@1
   185
      r.AppendLine();
moel@1
   186
      r.AppendFormat("Processor Vendor: {0}{1}", cpuVendor, 
moel@1
   187
        Environment.NewLine);
moel@1
   188
      r.AppendFormat("Processor Brand: {0}{1}", cpuBrandString, 
moel@1
   189
        Environment.NewLine);
moel@1
   190
      r.AppendFormat("Family: 0x{0}{1}", family.ToString("X"),
moel@1
   191
        Environment.NewLine);
moel@1
   192
      r.AppendFormat("Model: 0x{0}{1}", model.ToString("X"),
moel@1
   193
        Environment.NewLine);
moel@1
   194
      r.AppendFormat("Stepping: 0x{0}{1}", stepping.ToString("X"),
moel@1
   195
        Environment.NewLine);
moel@1
   196
      r.AppendLine();
moel@1
   197
moel@1
   198
      r.AppendLine("CPUID Return Values");
moel@1
   199
      r.AppendLine();
moel@1
   200
moel@18
   201
      if (cpuidData != null) {
moel@18
   202
        r.AppendLine(" Function  EAX       EBX       ECX       EDX");
moel@18
   203
        AppendCpuidData(r, cpuidData, CPUID);
moel@18
   204
        AppendCpuidData(r, cpuidExtData, CPUID_EXT);
moel@18
   205
        r.AppendLine();
moel@18
   206
      }
moel@1
   207
moel@1
   208
      return r.ToString();
moel@1
   209
    }
moel@1
   210
moel@1
   211
    public void Close() { }
moel@1
   212
  }
moel@1
   213
}