1.1 --- a/Hardware/CPU/IntelCPU.cs Sat Feb 13 17:08:36 2010 +0000
1.2 +++ b/Hardware/CPU/IntelCPU.cs Sun Feb 14 20:16:30 2010 +0000
1.3 @@ -51,6 +51,8 @@
1.4 private Sensor[] coreTemperatures;
1.5 private Sensor totalLoad;
1.6 private Sensor[] coreLoads;
1.7 + private Sensor[] coreClocks;
1.8 + private Sensor busClock;
1.9
1.10 private float tjMax = 0;
1.11 private uint logicalProcessors;
1.12 @@ -58,9 +60,13 @@
1.13 private uint coreCount;
1.14
1.15 private CPULoad cpuLoad;
1.16 +
1.17 + private ulong lastCount;
1.18 + private long lastTime;
1.19
1.20 private const uint IA32_THERM_STATUS_MSR = 0x019C;
1.21 private const uint IA32_TEMPERATURE_TARGET = 0x01A2;
1.22 + private const uint IA32_PERF_STATUS = 0x0198;
1.23
1.24 public IntelCPU(string name, uint family, uint model, uint stepping,
1.25 uint[,] cpuidData, uint[,] cpuidExtData) {
1.26 @@ -89,58 +95,64 @@
1.27
1.28 coreCount = logicalProcessors / logicalProcessorsPerCore;
1.29
1.30 - switch (family) {
1.31 - case 0x06: {
1.32 - switch (model) {
1.33 - case 0x0F: // Intel Core 65nm
1.34 - switch (stepping) {
1.35 - case 0x06: // B2
1.36 - switch (coreCount) {
1.37 - case 2:
1.38 + // check if processor supports a digital thermal sensor
1.39 + if (cpuidData.GetLength(0) > 6 && (cpuidData[6, 0] & 1) != 0) {
1.40 +
1.41 + switch (family) {
1.42 + case 0x06: {
1.43 + switch (model) {
1.44 + case 0x0F: // Intel Core 65nm
1.45 + switch (stepping) {
1.46 + case 0x06: // B2
1.47 + switch (coreCount) {
1.48 + case 2:
1.49 + tjMax = 80; break;
1.50 + case 4:
1.51 + tjMax = 90; break;
1.52 + default:
1.53 + tjMax = 85; break;
1.54 + }
1.55 tjMax = 80; break;
1.56 - case 4:
1.57 + case 0x0B: // G0
1.58 tjMax = 90; break;
1.59 + case 0x0D: // M0
1.60 + tjMax = 85; break;
1.61 default:
1.62 tjMax = 85; break;
1.63 - }
1.64 - tjMax = 80; break;
1.65 - case 0x0B: // G0
1.66 + } break;
1.67 + case 0x17: // Intel Core 45nm
1.68 + tjMax = 100; break;
1.69 + case 0x1C: // Intel Atom
1.70 tjMax = 90; break;
1.71 - case 0x0D: // M0
1.72 - tjMax = 85; break;
1.73 + case 0x1A:
1.74 + uint eax = 0, edx = 0;
1.75 + if (WinRing0.RdmsrPx(
1.76 + IA32_TEMPERATURE_TARGET, ref eax, ref edx, (UIntPtr)1)) {
1.77 + tjMax = (eax >> 16) & 0xFF;
1.78 + } else
1.79 + tjMax = 100;
1.80 + break;
1.81 default:
1.82 - tjMax = 85; break;
1.83 - } break;
1.84 - case 0x17: // Intel Core 45nm
1.85 - tjMax = 100; break;
1.86 - case 0x1C: // Intel Atom
1.87 - tjMax = 90; break;
1.88 - case 0x1A:
1.89 - uint eax = 0, edx = 0;
1.90 - if (WinRing0.RdmsrPx(
1.91 - IA32_TEMPERATURE_TARGET, ref eax, ref edx, (UIntPtr)1)) {
1.92 - tjMax = (eax >> 16) & 0xFF;
1.93 - } else
1.94 - tjMax = 100;
1.95 - break;
1.96 - default:
1.97 - tjMax = 100; break;
1.98 - }
1.99 - } break;
1.100 - default: tjMax = 100; break;
1.101 + tjMax = 100; break;
1.102 + }
1.103 + } break;
1.104 + default: tjMax = 100; break;
1.105 + }
1.106 +
1.107 + coreTemperatures = new Sensor[coreCount];
1.108 + for (int i = 0; i < coreTemperatures.Length; i++) {
1.109 + coreTemperatures[i] = new Sensor("Core #" + (i + 1), i, tjMax,
1.110 + SensorType.Temperature, this);
1.111 + }
1.112 + } else {
1.113 + coreTemperatures = new Sensor[0];
1.114 }
1.115 -
1.116 - totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this);
1.117 -
1.118 - coreTemperatures = new Sensor[coreCount];
1.119 +
1.120 + totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this);
1.121 coreLoads = new Sensor[coreCount];
1.122 - for (int i = 0; i < coreTemperatures.Length; i++) {
1.123 - coreTemperatures[i] = new Sensor("Core #" + (i + 1), i, tjMax,
1.124 - SensorType.Temperature, this);
1.125 - coreLoads[i] = new Sensor("Core #" + (i + 1), i + 1,
1.126 - SensorType.Load, this);
1.127 - }
1.128 -
1.129 + for (int i = 0; i < coreLoads.Length; i++)
1.130 + coreLoads[i] = new Sensor("Core #" + (i + 1), i + 1,
1.131 + SensorType.Load, this);
1.132 cpuLoad = new CPULoad(coreCount, logicalProcessorsPerCore);
1.133 if (cpuLoad.IsAvailable) {
1.134 foreach (Sensor sensor in coreLoads)
1.135 @@ -148,6 +160,16 @@
1.136 ActivateSensor(totalLoad);
1.137 }
1.138
1.139 + lastCount = 0;
1.140 + lastTime = 0;
1.141 + busClock = new Sensor("Bus Speed", 0, SensorType.Clock, this);
1.142 + coreClocks = new Sensor[coreCount];
1.143 + for (int i = 0; i < coreClocks.Length; i++) {
1.144 + coreClocks[i] =
1.145 + new Sensor("Core #" + (i + 1), i + 1, SensorType.Clock, this);
1.146 + ActivateSensor(coreClocks[i]);
1.147 + }
1.148 +
1.149 Update();
1.150 }
1.151
1.152 @@ -180,9 +202,9 @@
1.153 }
1.154
1.155 public void Update() {
1.156 -
1.157 - uint eax = 0, edx = 0;
1.158 +
1.159 for (int i = 0; i < coreTemperatures.Length; i++) {
1.160 + uint eax = 0, edx = 0;
1.161 if (WinRing0.RdmsrPx(
1.162 IA32_THERM_STATUS_MSR, ref eax, ref edx,
1.163 (UIntPtr)(1 << (int)(logicalProcessorsPerCore * i))))
1.164 @@ -204,6 +226,42 @@
1.165 coreLoads[i].Value = cpuLoad.GetCoreLoad(i);
1.166 totalLoad.Value = cpuLoad.GetTotalLoad();
1.167 }
1.168 +
1.169 + uint lsb = 0, msb = 0;
1.170 + bool valid = WinRing0.RdtscPx(ref lsb, ref msb, (UIntPtr)1);
1.171 + long time = Stopwatch.GetTimestamp();
1.172 + ulong count = ((ulong)msb << 32) | lsb;
1.173 + double delta = ((double)(time - lastTime)) / Stopwatch.Frequency;
1.174 + if (valid && delta > 0.5) {
1.175 + double maxClock = (float)((count - lastCount) / (1e6 * delta));
1.176 + double busClock = 0;
1.177 + uint eax, edx;
1.178 + for (int i = 0; i < coreClocks.Length; i++) {
1.179 + eax = 0; edx = 0;
1.180 + System.Threading.Thread.Sleep(1);
1.181 + if (WinRing0.RdmsrPx(IA32_PERF_STATUS, ref eax, ref edx,
1.182 + (UIntPtr)(1 << (int)(logicalProcessorsPerCore * i)))) {
1.183 + uint multiplier = (eax >> 8) & 0x1f;
1.184 + uint maxMultiplier = (edx >> 8) & 0x1f;
1.185 + // factor = multiplier * 2 to handle non integer multipliers
1.186 + uint factor = (multiplier << 1) | ((eax >> 14) & 1);
1.187 + uint maxFactor = (maxMultiplier << 1) | ((edx >> 14) & 1);
1.188 + if (maxFactor > 0) {
1.189 + coreClocks[i].Value = (float)(factor * maxClock / maxFactor);
1.190 + busClock = (float)(2 * maxClock / maxFactor);
1.191 + }
1.192 + } else {
1.193 + // if IA32_PERF_STATUS is not available, assume maxClock
1.194 + coreClocks[i].Value = (float)maxClock;
1.195 + }
1.196 + }
1.197 + if (busClock > 0) {
1.198 + this.busClock.Value = (float)busClock;
1.199 + ActivateSensor(this.busClock);
1.200 + }
1.201 + }
1.202 + lastCount = count;
1.203 + lastTime = time;
1.204 }
1.205 }
1.206 }