Added core and bus clock support for Intel CPUs (Core 2).
1.1 --- a/GUI/SensorNotifyIcon.cs Sat Feb 13 17:08:36 2010 +0000
1.2 +++ b/GUI/SensorNotifyIcon.cs Sun Feb 14 20:16:30 2010 +0000
1.3 @@ -107,9 +107,9 @@
1.4 set {
1.5 this.color = value;
1.6 this.darkColor = Color.FromArgb(255,
1.7 - Math.Max(this.color.R - 100, 0),
1.8 - Math.Max(this.color.G - 100, 0),
1.9 - Math.Max(this.color.B - 100, 0));
1.10 + this.color.R / 3,
1.11 + this.color.G / 3,
1.12 + this.color.B / 3);
1.13 Brush brush = this.brush;
1.14 this.brush = new SolidBrush(this.color);
1.15 if (brush != null)
2.1 --- a/Hardware/CPU/CPUGroup.cs Sat Feb 13 17:08:36 2010 +0000
2.2 +++ b/Hardware/CPU/CPUGroup.cs Sun Feb 14 20:16:30 2010 +0000
2.3 @@ -131,10 +131,8 @@
2.4
2.5 switch (cpuVendor) {
2.6 case "GenuineIntel":
2.7 - // check if processor supports a digital thermal sensor
2.8 - if (maxCPUID >= 6 && (cpuidData[6, 0] & 1) != 0)
2.9 - hardware.Add(new IntelCPU(name, family, model, stepping,
2.10 - cpuidData, cpuidExtData));
2.11 + hardware.Add(new IntelCPU(name, family, model, stepping,
2.12 + cpuidData, cpuidExtData));
2.13 break;
2.14 case "AuthenticAMD":
2.15 // check if processor supports a digital thermal sensor
3.1 --- a/Hardware/CPU/IntelCPU.cs Sat Feb 13 17:08:36 2010 +0000
3.2 +++ b/Hardware/CPU/IntelCPU.cs Sun Feb 14 20:16:30 2010 +0000
3.3 @@ -51,6 +51,8 @@
3.4 private Sensor[] coreTemperatures;
3.5 private Sensor totalLoad;
3.6 private Sensor[] coreLoads;
3.7 + private Sensor[] coreClocks;
3.8 + private Sensor busClock;
3.9
3.10 private float tjMax = 0;
3.11 private uint logicalProcessors;
3.12 @@ -58,9 +60,13 @@
3.13 private uint coreCount;
3.14
3.15 private CPULoad cpuLoad;
3.16 +
3.17 + private ulong lastCount;
3.18 + private long lastTime;
3.19
3.20 private const uint IA32_THERM_STATUS_MSR = 0x019C;
3.21 private const uint IA32_TEMPERATURE_TARGET = 0x01A2;
3.22 + private const uint IA32_PERF_STATUS = 0x0198;
3.23
3.24 public IntelCPU(string name, uint family, uint model, uint stepping,
3.25 uint[,] cpuidData, uint[,] cpuidExtData) {
3.26 @@ -89,58 +95,64 @@
3.27
3.28 coreCount = logicalProcessors / logicalProcessorsPerCore;
3.29
3.30 - switch (family) {
3.31 - case 0x06: {
3.32 - switch (model) {
3.33 - case 0x0F: // Intel Core 65nm
3.34 - switch (stepping) {
3.35 - case 0x06: // B2
3.36 - switch (coreCount) {
3.37 - case 2:
3.38 + // check if processor supports a digital thermal sensor
3.39 + if (cpuidData.GetLength(0) > 6 && (cpuidData[6, 0] & 1) != 0) {
3.40 +
3.41 + switch (family) {
3.42 + case 0x06: {
3.43 + switch (model) {
3.44 + case 0x0F: // Intel Core 65nm
3.45 + switch (stepping) {
3.46 + case 0x06: // B2
3.47 + switch (coreCount) {
3.48 + case 2:
3.49 + tjMax = 80; break;
3.50 + case 4:
3.51 + tjMax = 90; break;
3.52 + default:
3.53 + tjMax = 85; break;
3.54 + }
3.55 tjMax = 80; break;
3.56 - case 4:
3.57 + case 0x0B: // G0
3.58 tjMax = 90; break;
3.59 + case 0x0D: // M0
3.60 + tjMax = 85; break;
3.61 default:
3.62 tjMax = 85; break;
3.63 - }
3.64 - tjMax = 80; break;
3.65 - case 0x0B: // G0
3.66 + } break;
3.67 + case 0x17: // Intel Core 45nm
3.68 + tjMax = 100; break;
3.69 + case 0x1C: // Intel Atom
3.70 tjMax = 90; break;
3.71 - case 0x0D: // M0
3.72 - tjMax = 85; break;
3.73 + case 0x1A:
3.74 + uint eax = 0, edx = 0;
3.75 + if (WinRing0.RdmsrPx(
3.76 + IA32_TEMPERATURE_TARGET, ref eax, ref edx, (UIntPtr)1)) {
3.77 + tjMax = (eax >> 16) & 0xFF;
3.78 + } else
3.79 + tjMax = 100;
3.80 + break;
3.81 default:
3.82 - tjMax = 85; break;
3.83 - } break;
3.84 - case 0x17: // Intel Core 45nm
3.85 - tjMax = 100; break;
3.86 - case 0x1C: // Intel Atom
3.87 - tjMax = 90; break;
3.88 - case 0x1A:
3.89 - uint eax = 0, edx = 0;
3.90 - if (WinRing0.RdmsrPx(
3.91 - IA32_TEMPERATURE_TARGET, ref eax, ref edx, (UIntPtr)1)) {
3.92 - tjMax = (eax >> 16) & 0xFF;
3.93 - } else
3.94 - tjMax = 100;
3.95 - break;
3.96 - default:
3.97 - tjMax = 100; break;
3.98 - }
3.99 - } break;
3.100 - default: tjMax = 100; break;
3.101 + tjMax = 100; break;
3.102 + }
3.103 + } break;
3.104 + default: tjMax = 100; break;
3.105 + }
3.106 +
3.107 + coreTemperatures = new Sensor[coreCount];
3.108 + for (int i = 0; i < coreTemperatures.Length; i++) {
3.109 + coreTemperatures[i] = new Sensor("Core #" + (i + 1), i, tjMax,
3.110 + SensorType.Temperature, this);
3.111 + }
3.112 + } else {
3.113 + coreTemperatures = new Sensor[0];
3.114 }
3.115 -
3.116 - totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this);
3.117 -
3.118 - coreTemperatures = new Sensor[coreCount];
3.119 +
3.120 + totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this);
3.121 coreLoads = new Sensor[coreCount];
3.122 - for (int i = 0; i < coreTemperatures.Length; i++) {
3.123 - coreTemperatures[i] = new Sensor("Core #" + (i + 1), i, tjMax,
3.124 - SensorType.Temperature, this);
3.125 - coreLoads[i] = new Sensor("Core #" + (i + 1), i + 1,
3.126 - SensorType.Load, this);
3.127 - }
3.128 -
3.129 + for (int i = 0; i < coreLoads.Length; i++)
3.130 + coreLoads[i] = new Sensor("Core #" + (i + 1), i + 1,
3.131 + SensorType.Load, this);
3.132 cpuLoad = new CPULoad(coreCount, logicalProcessorsPerCore);
3.133 if (cpuLoad.IsAvailable) {
3.134 foreach (Sensor sensor in coreLoads)
3.135 @@ -148,6 +160,16 @@
3.136 ActivateSensor(totalLoad);
3.137 }
3.138
3.139 + lastCount = 0;
3.140 + lastTime = 0;
3.141 + busClock = new Sensor("Bus Speed", 0, SensorType.Clock, this);
3.142 + coreClocks = new Sensor[coreCount];
3.143 + for (int i = 0; i < coreClocks.Length; i++) {
3.144 + coreClocks[i] =
3.145 + new Sensor("Core #" + (i + 1), i + 1, SensorType.Clock, this);
3.146 + ActivateSensor(coreClocks[i]);
3.147 + }
3.148 +
3.149 Update();
3.150 }
3.151
3.152 @@ -180,9 +202,9 @@
3.153 }
3.154
3.155 public void Update() {
3.156 -
3.157 - uint eax = 0, edx = 0;
3.158 +
3.159 for (int i = 0; i < coreTemperatures.Length; i++) {
3.160 + uint eax = 0, edx = 0;
3.161 if (WinRing0.RdmsrPx(
3.162 IA32_THERM_STATUS_MSR, ref eax, ref edx,
3.163 (UIntPtr)(1 << (int)(logicalProcessorsPerCore * i))))
3.164 @@ -204,6 +226,42 @@
3.165 coreLoads[i].Value = cpuLoad.GetCoreLoad(i);
3.166 totalLoad.Value = cpuLoad.GetTotalLoad();
3.167 }
3.168 +
3.169 + uint lsb = 0, msb = 0;
3.170 + bool valid = WinRing0.RdtscPx(ref lsb, ref msb, (UIntPtr)1);
3.171 + long time = Stopwatch.GetTimestamp();
3.172 + ulong count = ((ulong)msb << 32) | lsb;
3.173 + double delta = ((double)(time - lastTime)) / Stopwatch.Frequency;
3.174 + if (valid && delta > 0.5) {
3.175 + double maxClock = (float)((count - lastCount) / (1e6 * delta));
3.176 + double busClock = 0;
3.177 + uint eax, edx;
3.178 + for (int i = 0; i < coreClocks.Length; i++) {
3.179 + eax = 0; edx = 0;
3.180 + System.Threading.Thread.Sleep(1);
3.181 + if (WinRing0.RdmsrPx(IA32_PERF_STATUS, ref eax, ref edx,
3.182 + (UIntPtr)(1 << (int)(logicalProcessorsPerCore * i)))) {
3.183 + uint multiplier = (eax >> 8) & 0x1f;
3.184 + uint maxMultiplier = (edx >> 8) & 0x1f;
3.185 + // factor = multiplier * 2 to handle non integer multipliers
3.186 + uint factor = (multiplier << 1) | ((eax >> 14) & 1);
3.187 + uint maxFactor = (maxMultiplier << 1) | ((edx >> 14) & 1);
3.188 + if (maxFactor > 0) {
3.189 + coreClocks[i].Value = (float)(factor * maxClock / maxFactor);
3.190 + busClock = (float)(2 * maxClock / maxFactor);
3.191 + }
3.192 + } else {
3.193 + // if IA32_PERF_STATUS is not available, assume maxClock
3.194 + coreClocks[i].Value = (float)maxClock;
3.195 + }
3.196 + }
3.197 + if (busClock > 0) {
3.198 + this.busClock.Value = (float)busClock;
3.199 + ActivateSensor(this.busClock);
3.200 + }
3.201 + }
3.202 + lastCount = count;
3.203 + lastTime = time;
3.204 }
3.205 }
3.206 }
4.1 --- a/Hardware/WinRing0.cs Sat Feb 13 17:08:36 2010 +0000
4.2 +++ b/Hardware/WinRing0.cs Sun Feb 14 20:16:30 2010 +0000
4.3 @@ -94,6 +94,8 @@
4.4 uint regAddress, out uint value);
4.5 public delegate bool WritePciConfigDwordExDelegate(uint pciAddress,
4.6 uint regAddress, uint value);
4.7 + public delegate bool RdtscPxDelegate(ref uint eax, ref uint edx,
4.8 + UIntPtr processAffinityMask);
4.9
4.10 private static InitializeOlsDelegate InitializeOls;
4.11 private static DeinitializeOlsDelegate DeinitializeOls;
4.12 @@ -108,7 +110,8 @@
4.13 public static SetPciMaxBusIndexDelegate SetPciMaxBusIndex;
4.14 public static FindPciDeviceByIdDelegate FindPciDeviceById;
4.15 public static ReadPciConfigDwordExDelegate ReadPciConfigDwordEx;
4.16 - public static WritePciConfigDwordExDelegate WritePciConfigDwordEx;
4.17 + public static WritePciConfigDwordExDelegate WritePciConfigDwordEx;
4.18 + public static RdtscPxDelegate RdtscPx;
4.19
4.20 private static void GetDelegate<T>(string entryPoint, out T newDelegate)
4.21 where T : class
4.22 @@ -135,6 +138,7 @@
4.23 GetDelegate("FindPciDeviceById", out FindPciDeviceById);
4.24 GetDelegate("ReadPciConfigDwordEx", out ReadPciConfigDwordEx);
4.25 GetDelegate("WritePciConfigDwordEx", out WritePciConfigDwordEx);
4.26 + GetDelegate("RdtscPx", out RdtscPx);
4.27
4.28 try {
4.29 if (InitializeOls != null && InitializeOls())
5.1 --- a/Properties/AssemblyInfo.cs Sat Feb 13 17:08:36 2010 +0000
5.2 +++ b/Properties/AssemblyInfo.cs Sun Feb 14 20:16:30 2010 +0000
5.3 @@ -69,5 +69,5 @@
5.4 // You can specify all the values or you can default the Build and Revision Numbers
5.5 // by using the '*' as shown below:
5.6 // [assembly: AssemblyVersion("1.0.*")]
5.7 -[assembly: AssemblyVersion("0.1.19.0")]
5.8 -[assembly: AssemblyFileVersion("0.1.19.0")]
5.9 +[assembly: AssemblyVersion("0.1.20.0")]
5.10 +[assembly: AssemblyFileVersion("0.1.20.0")]