Added core clock and bus speed support for Intel Core i5, i7 CPUs.
authormoel.mich
Mon, 15 Feb 2010 22:58:29 +0000
changeset 46f847947b7f8e
parent 45 eadad41d21a6
child 47 1d02fde1bb23
Added core clock and bus speed support for Intel Core i5, i7 CPUs.
Hardware/CPU/IntelCPU.cs
Hardware/WinRing0.cs
Properties/AssemblyInfo.cs
     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  }
     2.1 --- a/Hardware/WinRing0.cs	Sun Feb 14 21:09:08 2010 +0000
     2.2 +++ b/Hardware/WinRing0.cs	Mon Feb 15 22:58:29 2010 +0000
     2.3 @@ -83,8 +83,9 @@
     2.4        out uint eax, out uint ebx, out uint ecx, out uint edx);
     2.5      public delegate bool CpuidExDelegate(uint index, uint ecxValue, 
     2.6        out uint eax, out uint ebx, out uint ecx, out uint edx);
     2.7 -    public delegate bool RdmsrPxDelegate(uint index, ref uint eax, ref uint edx, 
     2.8 -      UIntPtr processAffinityMask);
     2.9 +    public delegate bool RdmsrDelegate(uint index, out uint eax, out uint edx);
    2.10 +    public delegate bool RdmsrTxDelegate(uint index, out uint eax, out uint edx,
    2.11 +      UIntPtr threadAffinityMask);
    2.12      public delegate byte ReadIoPortByteDelegate(ushort port);
    2.13      public delegate void WriteIoPortByteDelegate(ushort port, byte value);
    2.14      public delegate void SetPciMaxBusIndexDelegate(byte max);
    2.15 @@ -94,8 +95,8 @@
    2.16        uint regAddress, out uint value);
    2.17      public delegate bool WritePciConfigDwordExDelegate(uint pciAddress, 
    2.18        uint regAddress, uint value);
    2.19 -    public delegate bool RdtscPxDelegate(ref uint eax, ref uint edx,
    2.20 -      UIntPtr processAffinityMask);
    2.21 +    public delegate bool RdtscTxDelegate(out uint eax, out uint edx,
    2.22 +      UIntPtr threadAffinityMask);
    2.23  
    2.24      private static InitializeOlsDelegate InitializeOls;
    2.25      private static DeinitializeOlsDelegate DeinitializeOls;
    2.26 @@ -104,14 +105,15 @@
    2.27      public static IsCpuidDelegate IsCpuid;
    2.28      public static CpuidDelegate Cpuid;
    2.29      public static CpuidExDelegate CpuidEx;
    2.30 -    public static RdmsrPxDelegate RdmsrPx;
    2.31 +    public static RdmsrDelegate Rdmsr;
    2.32 +    public static RdmsrTxDelegate RdmsrTx;
    2.33      public static ReadIoPortByteDelegate ReadIoPortByte;
    2.34      public static WriteIoPortByteDelegate WriteIoPortByte;
    2.35      public static SetPciMaxBusIndexDelegate SetPciMaxBusIndex;
    2.36      public static FindPciDeviceByIdDelegate FindPciDeviceById;
    2.37      public static ReadPciConfigDwordExDelegate ReadPciConfigDwordEx;
    2.38      public static WritePciConfigDwordExDelegate WritePciConfigDwordEx;
    2.39 -    public static RdtscPxDelegate RdtscPx;
    2.40 +    public static RdtscTxDelegate RdtscTx;
    2.41  
    2.42      private static void GetDelegate<T>(string entryPoint, out T newDelegate) 
    2.43        where T : class 
    2.44 @@ -131,14 +133,15 @@
    2.45        GetDelegate("IsCpuid", out IsCpuid);
    2.46        GetDelegate("Cpuid", out Cpuid);
    2.47        GetDelegate("CpuidEx", out CpuidEx);
    2.48 -      GetDelegate("RdmsrPx", out  RdmsrPx);
    2.49 +      GetDelegate("Rdmsr", out  Rdmsr);
    2.50 +      GetDelegate("RdmsrTx", out  RdmsrTx);
    2.51        GetDelegate("ReadIoPortByte", out ReadIoPortByte);
    2.52        GetDelegate("WriteIoPortByte", out WriteIoPortByte);
    2.53        GetDelegate("SetPciMaxBusIndex", out SetPciMaxBusIndex);
    2.54        GetDelegate("FindPciDeviceById", out FindPciDeviceById);
    2.55        GetDelegate("ReadPciConfigDwordEx", out ReadPciConfigDwordEx);
    2.56        GetDelegate("WritePciConfigDwordEx", out WritePciConfigDwordEx);
    2.57 -      GetDelegate("RdtscPx", out RdtscPx);
    2.58 +      GetDelegate("RdtscTx", out RdtscTx);
    2.59  
    2.60        try {
    2.61          if (InitializeOls != null && InitializeOls())
     3.1 --- a/Properties/AssemblyInfo.cs	Sun Feb 14 21:09:08 2010 +0000
     3.2 +++ b/Properties/AssemblyInfo.cs	Mon Feb 15 22:58:29 2010 +0000
     3.3 @@ -69,5 +69,5 @@
     3.4  // You can specify all the values or you can default the Build and Revision Numbers 
     3.5  // by using the '*' as shown below:
     3.6  // [assembly: AssemblyVersion("1.0.*")]
     3.7 -[assembly: AssemblyVersion("0.1.20.1")]
     3.8 -[assembly: AssemblyFileVersion("0.1.20.1")]
     3.9 +[assembly: AssemblyVersion("0.1.21.0")]
    3.10 +[assembly: AssemblyFileVersion("0.1.21.0")]