Added core and bus clock support for Intel CPUs (Core 2).
authormoel.mich
Sun, 14 Feb 2010 20:16:30 +0000
changeset 44c150de283ca0
parent 43 5b7398d061b7
child 45 eadad41d21a6
Added core and bus clock support for Intel CPUs (Core 2).
GUI/SensorNotifyIcon.cs
Hardware/CPU/CPUGroup.cs
Hardware/CPU/IntelCPU.cs
Hardware/WinRing0.cs
Properties/AssemblyInfo.cs
     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")]