Hardware/CPU/IntelCPU.cs
changeset 49 b418098ceca3
parent 46 f847947b7f8e
child 52 8495c0ee29ac
     1.1 --- a/Hardware/CPU/IntelCPU.cs	Wed Feb 17 18:48:27 2010 +0000
     1.2 +++ b/Hardware/CPU/IntelCPU.cs	Wed Feb 17 20:22:21 2010 +0000
     1.3 @@ -74,6 +74,13 @@
     1.4      private const uint IA32_PERF_STATUS = 0x0198;
     1.5      private const uint MSR_PLATFORM_INFO = 0xCE;
     1.6  
     1.7 +    private string CoreString(int i) {
     1.8 +      if (coreCount == 1)
     1.9 +        return "CPU Core";
    1.10 +      else
    1.11 +        return "CPU Core #" + (i + 1);
    1.12 +    }
    1.13 +
    1.14      public IntelCPU(string name, uint family, uint model, uint stepping, 
    1.15        uint[,] cpuidData, uint[,] cpuidExtData) {
    1.16        
    1.17 @@ -95,8 +102,15 @@
    1.18          }   
    1.19        }
    1.20        if (logicalProcessors <= 0 && cpuidData.GetLength(0) > 0x04) {
    1.21 -        logicalProcessors = ((cpuidData[4, 0] >> 26) & 0x3F) + 1;
    1.22 -        logicalProcessorsPerCore = 1;
    1.23 +        uint coresPerPackage = ((cpuidData[4, 0] >> 26) & 0x3F) + 1;
    1.24 +        uint logicalPerPackage = (cpuidData[1, 1] >> 16) & 0xFF;        
    1.25 +        logicalProcessorsPerCore = logicalPerPackage / coresPerPackage;
    1.26 +        logicalProcessors = logicalPerPackage;
    1.27 +      }
    1.28 +      if (logicalProcessors <= 0 && cpuidData.GetLength(0) > 0x01) {
    1.29 +        uint logicalPerPackage = (cpuidData[1, 1] >> 16) & 0xFF;
    1.30 +        logicalProcessorsPerCore = logicalPerPackage;
    1.31 +        logicalProcessors = logicalPerPackage;
    1.32        }
    1.33        if (logicalProcessors <= 0) {
    1.34          logicalProcessors = 1;
    1.35 @@ -104,78 +118,78 @@
    1.36        }
    1.37  
    1.38        coreCount = logicalProcessors / logicalProcessorsPerCore;
    1.39 +      
    1.40 +      switch (family) {
    1.41 +        case 0x06: {
    1.42 +            switch (model) {
    1.43 +              case 0x0F: // Intel Core (65nm)
    1.44 +                switch (stepping) {
    1.45 +                  case 0x06: // B2
    1.46 +                    switch (coreCount) {
    1.47 +                      case 2:
    1.48 +                        tjMax = 80; break;
    1.49 +                      case 4:
    1.50 +                        tjMax = 90; break;
    1.51 +                      default:
    1.52 +                        tjMax = 85; break;
    1.53 +                    }
    1.54 +                    tjMax = 80; break;
    1.55 +                  case 0x0B: // G0
    1.56 +                    tjMax = 90; break;
    1.57 +                  case 0x0D: // M0
    1.58 +                    tjMax = 85; break;
    1.59 +                  default:
    1.60 +                    tjMax = 85; break;
    1.61 +                } break;
    1.62 +              case 0x17: // Intel Core (45nm)
    1.63 +                tjMax = 100; break;
    1.64 +              case 0x1C: // Intel Atom 
    1.65 +                tjMax = 90; break;
    1.66 +              case 0x1A: // Intel Core i7 LGA1366 (45nm)
    1.67 +              case 0x1E: // Intel Core i5, i7 LGA1156 (45nm)
    1.68 +              case 0x25: // Intel Core i3, i5, i7 LGA1156 (32nm)
    1.69 +                uint eax, edx;
    1.70 +                if (WinRing0.Rdmsr(IA32_TEMPERATURE_TARGET, out eax, out edx)) {
    1.71 +                  tjMax = (eax >> 16) & 0xFF;
    1.72 +                } else {
    1.73 +                  tjMax = 100;
    1.74 +                }
    1.75 +                if (WinRing0.Rdmsr(MSR_PLATFORM_INFO, out eax, out edx)) {
    1.76 +                  maxNehalemMultiplier = (eax >> 8) & 0xff;
    1.77 +                }
    1.78 +                break;
    1.79 +              default:
    1.80 +                tjMax = 100; break;
    1.81 +            }
    1.82 +          } break;
    1.83 +        default: tjMax = 100; break;
    1.84 +      }
    1.85  
    1.86        // check if processor supports a digital thermal sensor
    1.87        if (cpuidData.GetLength(0) > 6 && (cpuidData[6, 0] & 1) != 0) {
    1.88 -
    1.89 -        switch (family) {
    1.90 -          case 0x06: {
    1.91 -              switch (model) {
    1.92 -                case 0x0F: // Intel Core 65nm
    1.93 -                  switch (stepping) {
    1.94 -                    case 0x06: // B2
    1.95 -                      switch (coreCount) {
    1.96 -                        case 2:
    1.97 -                          tjMax = 80; break;
    1.98 -                        case 4:
    1.99 -                          tjMax = 90; break;
   1.100 -                        default:
   1.101 -                          tjMax = 85; break;
   1.102 -                      }
   1.103 -                      tjMax = 80; break;
   1.104 -                    case 0x0B: // G0
   1.105 -                      tjMax = 90; break;
   1.106 -                    case 0x0D: // M0
   1.107 -                      tjMax = 85; break;
   1.108 -                    default:
   1.109 -                      tjMax = 85; break;
   1.110 -                  } break;
   1.111 -                case 0x17: // Intel Core 45nm
   1.112 -                  tjMax = 100; break;
   1.113 -                case 0x1C: // Intel Atom 
   1.114 -                  tjMax = 90; break;
   1.115 -                case 0x1A: // Intel Core i7
   1.116 -                case 0x1E: // Intel Core i5
   1.117 -                  uint eax, edx;
   1.118 -                  if (WinRing0.Rdmsr(IA32_TEMPERATURE_TARGET, out eax, out edx)) 
   1.119 -                  {
   1.120 -                    tjMax = (eax >> 16) & 0xFF;
   1.121 -                  } else
   1.122 -                    tjMax = 100;
   1.123 -                  break;
   1.124 -                default:
   1.125 -                  tjMax = 100; break;
   1.126 -              }
   1.127 -            } break;
   1.128 -          default: tjMax = 100; break;
   1.129 -        }
   1.130 -
   1.131 -        if (family == 0x06 && model >= 0x1A) { // Core i5, i7
   1.132 -          uint eax, edx;
   1.133 -          if (WinRing0.Rdmsr(MSR_PLATFORM_INFO, out eax, out edx)) {
   1.134 -            maxNehalemMultiplier = (eax >> 8) & 0xff;
   1.135 -          }
   1.136 -        }
   1.137 -
   1.138          coreTemperatures = new Sensor[coreCount];
   1.139          for (int i = 0; i < coreTemperatures.Length; i++) {
   1.140 -          coreTemperatures[i] = new Sensor("Core #" + (i + 1), i, tjMax,
   1.141 +          coreTemperatures[i] = new Sensor(CoreString(i), i, tjMax,
   1.142              SensorType.Temperature, this);
   1.143          }
   1.144        } else {
   1.145          coreTemperatures = new Sensor[0];
   1.146        }
   1.147 -              
   1.148 -      totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this);   
   1.149 +
   1.150 +      if (coreCount > 1)
   1.151 +        totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this);
   1.152 +      else
   1.153 +        totalLoad = null;
   1.154        coreLoads = new Sensor[coreCount];
   1.155 -      for (int i = 0; i < coreLoads.Length; i++) 
   1.156 -        coreLoads[i] = new Sensor("Core #" + (i + 1), i + 1,
   1.157 +      for (int i = 0; i < coreLoads.Length; i++)
   1.158 +        coreLoads[i] = new Sensor(CoreString(i), i + 1,
   1.159            SensorType.Load, this);     
   1.160        cpuLoad = new CPULoad(coreCount, logicalProcessorsPerCore);
   1.161        if (cpuLoad.IsAvailable) {
   1.162          foreach (Sensor sensor in coreLoads)
   1.163            ActivateSensor(sensor);
   1.164 -        ActivateSensor(totalLoad);
   1.165 +        if (totalLoad != null)
   1.166 +          ActivateSensor(totalLoad);
   1.167        }
   1.168  
   1.169        lastCount = 0;
   1.170 @@ -183,8 +197,8 @@
   1.171        busClock = new Sensor("Bus Speed", 0, SensorType.Clock, this);      
   1.172        coreClocks = new Sensor[coreCount];
   1.173        for (int i = 0; i < coreClocks.Length; i++) {
   1.174 -        coreClocks[i] = 
   1.175 -          new Sensor("Core #" + (i + 1), i + 1, SensorType.Clock, this);
   1.176 +        coreClocks[i] =
   1.177 +          new Sensor(CoreString(i), i + 1, SensorType.Clock, this);
   1.178          ActivateSensor(coreClocks[i]);
   1.179        }
   1.180        
   1.181 @@ -203,6 +217,20 @@
   1.182        get { return icon; }
   1.183      }
   1.184  
   1.185 +    private void AppendMSRData(StringBuilder r, uint msr, int core) {
   1.186 +      uint eax, edx;
   1.187 +      if (WinRing0.RdmsrTx(msr, out eax, out edx,
   1.188 +         (UIntPtr)(1 << (int)(logicalProcessorsPerCore * core)))) {
   1.189 +        r.Append(" ");
   1.190 +        r.Append((msr).ToString("X8"));
   1.191 +        r.Append("  ");
   1.192 +        r.Append((edx).ToString("X8"));
   1.193 +        r.Append("  ");
   1.194 +        r.Append((eax).ToString("X8"));
   1.195 +        r.AppendLine();
   1.196 +      }
   1.197 +    }
   1.198 +
   1.199      public string GetReport() {
   1.200        StringBuilder r = new StringBuilder();
   1.201  
   1.202 @@ -216,6 +244,17 @@
   1.203        r.AppendFormat("TjMax: {0}{1}", tjMax, Environment.NewLine);
   1.204        r.AppendLine();
   1.205  
   1.206 +      for (int i = 0; i < coreCount; i++) {
   1.207 +        r.AppendLine("MSR Core #" + (i + 1));
   1.208 +        r.AppendLine();
   1.209 +        r.AppendLine(" MSR       EDX       EAX");
   1.210 +        AppendMSRData(r, MSR_PLATFORM_INFO, i);
   1.211 +        AppendMSRData(r, IA32_PERF_STATUS, i);
   1.212 +        AppendMSRData(r, IA32_THERM_STATUS_MSR, i);
   1.213 +        AppendMSRData(r, IA32_TEMPERATURE_TARGET, i);
   1.214 +        r.AppendLine();
   1.215 +      }
   1.216 +
   1.217        return r.ToString();
   1.218      }
   1.219  
   1.220 @@ -242,7 +281,8 @@
   1.221          cpuLoad.Update();
   1.222          for (int i = 0; i < coreLoads.Length; i++)
   1.223            coreLoads[i].Value = cpuLoad.GetCoreLoad(i);
   1.224 -        totalLoad.Value = cpuLoad.GetTotalLoad();
   1.225 +        if (totalLoad != null)
   1.226 +          totalLoad.Value = cpuLoad.GetTotalLoad();
   1.227        }
   1.228       
   1.229        uint lsb, msb;
   1.230 @@ -258,7 +298,12 @@
   1.231            System.Threading.Thread.Sleep(1);
   1.232            if (WinRing0.RdmsrTx(IA32_PERF_STATUS, out eax, out edx,
   1.233              (UIntPtr)(1 << (int)(logicalProcessorsPerCore * i)))) {
   1.234 -            if (model < 0x1A) { // Core 2
   1.235 +            if (maxNehalemMultiplier > 0) { // Core i3, i5, i7
   1.236 +              uint nehalemMultiplier = eax & 0xff;
   1.237 +              coreClocks[i].Value =
   1.238 +                (float)(nehalemMultiplier * maxClock / maxNehalemMultiplier);
   1.239 +              busClock = (float)(maxClock / maxNehalemMultiplier);
   1.240 +            } else { // Core 2
   1.241                uint multiplier = (eax >> 8) & 0x1f;
   1.242                uint maxMultiplier = (edx >> 8) & 0x1f;
   1.243                // factor = multiplier * 2 to handle non integer multipliers 
   1.244 @@ -268,14 +313,7 @@
   1.245                  coreClocks[i].Value = (float)(factor * maxClock / maxFactor);
   1.246                  busClock = (float)(2 * maxClock / maxFactor);
   1.247                }
   1.248 -            } else { // Core i5, i7
   1.249 -              uint nehalemMultiplier = eax & 0xff;
   1.250 -              if (maxNehalemMultiplier > 0) {
   1.251 -                coreClocks[i].Value =
   1.252 -                  (float)(nehalemMultiplier * maxClock / maxNehalemMultiplier);
   1.253 -                busClock = (float)(maxClock / maxNehalemMultiplier);
   1.254 -              }
   1.255 -            }
   1.256 +            }  
   1.257            } else { // Intel Pentium 4
   1.258              // if IA32_PERF_STATUS is not available, assume maxClock
   1.259              coreClocks[i].Value = (float)maxClock;