1.1 --- a/Hardware/CPU/IntelCPU.cs Sun Feb 14 21:09:08 2010 +0000
1.2 +++ b/Hardware/CPU/IntelCPU.cs Mon Feb 15 22:58:29 2010 +0000
1.3 @@ -48,6 +48,10 @@
1.4 private string name;
1.5 private Image icon;
1.6
1.7 + private uint family;
1.8 + private uint model;
1.9 + private uint stepping;
1.10 +
1.11 private Sensor[] coreTemperatures;
1.12 private Sensor totalLoad;
1.13 private Sensor[] coreLoads;
1.14 @@ -63,17 +67,23 @@
1.15
1.16 private ulong lastCount;
1.17 private long lastTime;
1.18 + private uint maxNehalemMultiplier = 0;
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 + private const uint MSR_PLATFORM_INFO = 0xCE;
1.24
1.25 public IntelCPU(string name, uint family, uint model, uint stepping,
1.26 uint[,] cpuidData, uint[,] cpuidExtData) {
1.27
1.28 this.name = name;
1.29 this.icon = Utilities.EmbeddedResources.GetImage("cpu.png");
1.30 -
1.31 +
1.32 + this.family = family;
1.33 + this.model = model;
1.34 + this.stepping = stepping;
1.35 +
1.36 logicalProcessors = 0;
1.37 if (cpuidData.GetLength(0) > 0x0B) {
1.38 uint eax, ebx, ecx, edx;
1.39 @@ -124,10 +134,11 @@
1.40 tjMax = 100; break;
1.41 case 0x1C: // Intel Atom
1.42 tjMax = 90; break;
1.43 - case 0x1A:
1.44 - uint eax = 0, edx = 0;
1.45 - if (WinRing0.RdmsrPx(
1.46 - IA32_TEMPERATURE_TARGET, ref eax, ref edx, (UIntPtr)1)) {
1.47 + case 0x1A: // Intel Core i7
1.48 + case 0x1E: // Intel Core i5
1.49 + uint eax, edx;
1.50 + if (WinRing0.Rdmsr(IA32_TEMPERATURE_TARGET, out eax, out edx))
1.51 + {
1.52 tjMax = (eax >> 16) & 0xFF;
1.53 } else
1.54 tjMax = 100;
1.55 @@ -139,6 +150,13 @@
1.56 default: tjMax = 100; break;
1.57 }
1.58
1.59 + if (family == 0x06 && model >= 0x1A) { // Core i5, i7
1.60 + uint eax, edx;
1.61 + if (WinRing0.Rdmsr(MSR_PLATFORM_INFO, out eax, out edx)) {
1.62 + maxNehalemMultiplier = (eax >> 8) & 0xff;
1.63 + }
1.64 + }
1.65 +
1.66 coreTemperatures = new Sensor[coreCount];
1.67 for (int i = 0; i < coreTemperatures.Length; i++) {
1.68 coreTemperatures[i] = new Sensor("Core #" + (i + 1), i, tjMax,
1.69 @@ -204,9 +222,9 @@
1.70 public void Update() {
1.71
1.72 for (int i = 0; i < coreTemperatures.Length; i++) {
1.73 - uint eax = 0, edx = 0;
1.74 - if (WinRing0.RdmsrPx(
1.75 - IA32_THERM_STATUS_MSR, ref eax, ref edx,
1.76 + uint eax, edx;
1.77 + if (WinRing0.RdmsrTx(
1.78 + IA32_THERM_STATUS_MSR, out eax, out edx,
1.79 (UIntPtr)(1 << (int)(logicalProcessorsPerCore * i))))
1.80 {
1.81 // if reading is valid
1.82 @@ -227,33 +245,41 @@
1.83 totalLoad.Value = cpuLoad.GetTotalLoad();
1.84 }
1.85
1.86 - uint lsb = 0, msb = 0;
1.87 - bool valid = WinRing0.RdtscPx(ref lsb, ref msb, (UIntPtr)1);
1.88 + uint lsb, msb;
1.89 + bool valid = WinRing0.RdtscTx(out lsb, out msb, (UIntPtr)1);
1.90 long time = Stopwatch.GetTimestamp();
1.91 ulong count = ((ulong)msb << 32) | lsb;
1.92 double delta = ((double)(time - lastTime)) / Stopwatch.Frequency;
1.93 if (valid && delta > 0.5) {
1.94 - double maxClock = (float)((count - lastCount) / (1e6 * delta));
1.95 + double maxClock = (count - lastCount) / (1e6 * delta);
1.96 double busClock = 0;
1.97 - uint eax, edx;
1.98 + uint eax, edx;
1.99 for (int i = 0; i < coreClocks.Length; i++) {
1.100 - eax = 0; edx = 0;
1.101 System.Threading.Thread.Sleep(1);
1.102 - if (WinRing0.RdmsrPx(IA32_PERF_STATUS, ref eax, ref edx,
1.103 + if (WinRing0.RdmsrTx(IA32_PERF_STATUS, out eax, out edx,
1.104 (UIntPtr)(1 << (int)(logicalProcessorsPerCore * i)))) {
1.105 - uint multiplier = (eax >> 8) & 0x1f;
1.106 - uint maxMultiplier = (edx >> 8) & 0x1f;
1.107 - // factor = multiplier * 2 to handle non integer multipliers
1.108 - uint factor = (multiplier << 1) | ((eax >> 14) & 1);
1.109 - uint maxFactor = (maxMultiplier << 1) | ((edx >> 14) & 1);
1.110 - if (maxFactor > 0) {
1.111 - coreClocks[i].Value = (float)(factor * maxClock / maxFactor);
1.112 - busClock = (float)(2 * maxClock / maxFactor);
1.113 + if (model < 0x1A) { // Core 2
1.114 + uint multiplier = (eax >> 8) & 0x1f;
1.115 + uint maxMultiplier = (edx >> 8) & 0x1f;
1.116 + // factor = multiplier * 2 to handle non integer multipliers
1.117 + uint factor = (multiplier << 1) | ((eax >> 14) & 1);
1.118 + uint maxFactor = (maxMultiplier << 1) | ((edx >> 14) & 1);
1.119 + if (maxFactor > 0) {
1.120 + coreClocks[i].Value = (float)(factor * maxClock / maxFactor);
1.121 + busClock = (float)(2 * maxClock / maxFactor);
1.122 + }
1.123 + } else { // Core i5, i7
1.124 + uint nehalemMultiplier = eax & 0xff;
1.125 + if (maxNehalemMultiplier > 0) {
1.126 + coreClocks[i].Value =
1.127 + (float)(nehalemMultiplier * maxClock / maxNehalemMultiplier);
1.128 + busClock = (float)(maxClock / maxNehalemMultiplier);
1.129 + }
1.130 }
1.131 - } else {
1.132 + } else { // Intel Pentium 4
1.133 // if IA32_PERF_STATUS is not available, assume maxClock
1.134 coreClocks[i].Value = (float)maxClock;
1.135 - }
1.136 + }
1.137 }
1.138 if (busClock > 0) {
1.139 this.busClock.Value = (float)busClock;
1.140 @@ -262,6 +288,6 @@
1.141 }
1.142 lastCount = count;
1.143 lastTime = time;
1.144 - }
1.145 - }
1.146 + }
1.147 + }
1.148 }