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;