A first (experimental) implementation for the AMD 10h family CPU clock speeds.
authormoel.mich
Wed, 22 Sep 2010 20:44:34 +0000
changeset 197fb66f749b7ff
parent 196 5e9a8595296c
child 198 d5de6fa31bc6
A first (experimental) implementation for the AMD 10h family CPU clock speeds.
Hardware/CPU/AMD0FCPU.cs
Hardware/CPU/AMD10CPU.cs
Hardware/CPU/AMDCPU.cs
Properties/AssemblyVersion.cs
     1.1 --- a/Hardware/CPU/AMD0FCPU.cs	Wed Sep 22 19:12:12 2010 +0000
     1.2 +++ b/Hardware/CPU/AMD0FCPU.cs	Wed Sep 22 20:44:34 2010 +0000
     1.3 @@ -107,7 +107,7 @@
     1.4        StringBuilder r = new StringBuilder();
     1.5        r.Append(base.GetReport());
     1.6  
     1.7 -      r.Append("Miscellaneous Control Address: ");
     1.8 +      r.Append("Miscellaneous Control Address: 0x");
     1.9        r.AppendLine((miscellaneousControlAddress).ToString("X", 
    1.10          CultureInfo.InvariantCulture));
    1.11        r.AppendLine();
     2.1 --- a/Hardware/CPU/AMD10CPU.cs	Wed Sep 22 19:12:12 2010 +0000
     2.2 +++ b/Hardware/CPU/AMD10CPU.cs	Wed Sep 22 20:44:34 2010 +0000
     2.3 @@ -38,16 +38,22 @@
     2.4  using System;
     2.5  using System.Globalization;
     2.6  using System.Text;
     2.7 +using System.Threading;
     2.8  
     2.9  namespace OpenHardwareMonitor.Hardware.CPU {
    2.10  
    2.11    internal sealed class AMD10CPU : AMDCPU {
    2.12  
    2.13      private readonly Sensor coreTemperature;
    2.14 +    private readonly Sensor[] coreClocks;
    2.15 +    private readonly Sensor busClock;
    2.16 +
    2.17 +    private const uint COFVID_STATUS = 0xC0010071;
    2.18 +    private const uint P_STATE_0 = 0xC0010064;
    2.19  
    2.20      private const byte MISCELLANEOUS_CONTROL_FUNCTION = 3;
    2.21      private const ushort MISCELLANEOUS_CONTROL_DEVICE_ID = 0x1203;
    2.22 -    private const byte REPORTED_TEMPERATURE_CONTROL_REGISTER = 0xA4;
    2.23 +    private const uint REPORTED_TEMPERATURE_CONTROL_REGISTER = 0xA4;
    2.24      
    2.25      private readonly uint miscellaneousControlAddress;
    2.26  
    2.27 @@ -65,18 +71,27 @@
    2.28        miscellaneousControlAddress = GetPciAddress(
    2.29          MISCELLANEOUS_CONTROL_FUNCTION, MISCELLANEOUS_CONTROL_DEVICE_ID);
    2.30  
    2.31 +      busClock = new Sensor("Bus Speed", 0, SensorType.Clock, this, settings);
    2.32 +      coreClocks = new Sensor[coreCount];
    2.33 +      for (int i = 0; i < coreClocks.Length; i++) {
    2.34 +        coreClocks[i] = new Sensor(CoreString(i), i + 1, SensorType.Clock,
    2.35 +          this, settings);
    2.36 +        if (hasTSC)
    2.37 +          ActivateSensor(coreClocks[i]);
    2.38 +      }
    2.39 +
    2.40        Update();                   
    2.41      }
    2.42  
    2.43      protected override uint[] GetMSRs() {
    2.44 -      return new uint[] { };
    2.45 +      return new uint[] { P_STATE_0, COFVID_STATUS };
    2.46      }
    2.47  
    2.48      public override string GetReport() {
    2.49        StringBuilder r = new StringBuilder();
    2.50        r.Append(base.GetReport());
    2.51  
    2.52 -      r.Append("Miscellaneous Control Address: ");
    2.53 +      r.Append("Miscellaneous Control Address: 0x");
    2.54        r.AppendLine((miscellaneousControlAddress).ToString("X",
    2.55          CultureInfo.InvariantCulture));
    2.56        r.AppendLine();
    2.57 @@ -84,6 +99,10 @@
    2.58        return r.ToString();
    2.59      }
    2.60  
    2.61 +    private double MultiplierFromIDs(uint divisorID, uint frequencyID) {
    2.62 +      return 0.5 * (frequencyID + 0x10) / (1 << (int)divisorID);
    2.63 +    }
    2.64 +
    2.65      public override void Update() {
    2.66        base.Update();
    2.67  
    2.68 @@ -98,6 +117,44 @@
    2.69            DeactivateSensor(coreTemperature);
    2.70          }
    2.71        }
    2.72 -    }
    2.73 +
    2.74 +      if (hasTSC) {
    2.75 +        double newBusClock = 0;
    2.76 +
    2.77 +        for (int i = 0; i < coreClocks.Length; i++) {
    2.78 +          Thread.Sleep(1);
    2.79 +
    2.80 +          uint curEax, curEdx;
    2.81 +          uint maxEax, maxEdx;
    2.82 +          if (WinRing0.RdmsrTx(COFVID_STATUS, out curEax, out curEdx,
    2.83 +            (UIntPtr)(1L << cpuid[i][0].Thread)) &&
    2.84 +            WinRing0.RdmsrTx(P_STATE_0, out maxEax, out maxEdx,
    2.85 +            (UIntPtr)(1L << cpuid[i][0].Thread))) 
    2.86 +          {
    2.87 +            // 8:6 CpuDid: current core divisor ID
    2.88 +            // 5:0 CpuFid: current core frequency ID
    2.89 +            uint curCpuDid = (curEax >> 6) & 7;
    2.90 +            uint curCpuFid = curEax & 0x1F;
    2.91 +            double multiplier = MultiplierFromIDs(curCpuDid, curCpuFid);
    2.92 +
    2.93 +            // we assume that the max multiplier (used for the TSC) 
    2.94 +            // can be found in the P_STATE_0 MSR
    2.95 +            uint maxCpuDid = (maxEax >> 6) & 7;
    2.96 +            uint maxCpuFid = maxEax & 0x1F;
    2.97 +            double maxMultiplier = MultiplierFromIDs(maxCpuDid, maxCpuFid);
    2.98 +
    2.99 +            coreClocks[i].Value = (float)(multiplier * MaxClock / maxMultiplier);
   2.100 +            newBusClock = (float)(MaxClock / maxMultiplier);
   2.101 +          } else {
   2.102 +            coreClocks[i].Value = (float)MaxClock;
   2.103 +          }
   2.104 +        }
   2.105 +
   2.106 +        if (newBusClock > 0) {
   2.107 +          this.busClock.Value = (float)newBusClock;
   2.108 +          ActivateSensor(this.busClock);
   2.109 +        }
   2.110 +      }
   2.111 +    } 
   2.112    }
   2.113  }
     3.1 --- a/Hardware/CPU/AMDCPU.cs	Wed Sep 22 19:12:12 2010 +0000
     3.2 +++ b/Hardware/CPU/AMDCPU.cs	Wed Sep 22 20:44:34 2010 +0000
     3.3 @@ -48,14 +48,17 @@
     3.4        : base(processorIndex, cpuid, settings) { }
     3.5  
     3.6      protected uint GetPciAddress(byte function, ushort deviceId) {
     3.7 +      
     3.8 +      // assemble the pci address
     3.9        uint address = WinRing0.GetPciAddress(PCI_BUS,
    3.10          (byte)(PCI_BASE_DEVICE + processorIndex), function);
    3.11  
    3.12 +      // verify that we have the correct bus, device and function
    3.13        uint deviceVendor;
    3.14        if (!WinRing0.ReadPciConfigDwordEx(
    3.15          address, DEVICE_VENDOR_ID_REGISTER, out deviceVendor))
    3.16          return WinRing0.InvalidPciAddress;
    3.17 -
    3.18 +      
    3.19        if (deviceVendor != (deviceId << 16 | AMD_VENDOR_ID))
    3.20          return WinRing0.InvalidPciAddress;
    3.21  
     4.1 --- a/Properties/AssemblyVersion.cs	Wed Sep 22 19:12:12 2010 +0000
     4.2 +++ b/Properties/AssemblyVersion.cs	Wed Sep 22 20:44:34 2010 +0000
     4.3 @@ -37,5 +37,5 @@
     4.4  
     4.5  using System.Reflection;
     4.6  
     4.7 -[assembly: AssemblyVersion("0.1.37.14")]
     4.8 -[assembly: AssemblyInformationalVersion("0.1.37.14 Alpha")]
     4.9 \ No newline at end of file
    4.10 +[assembly: AssemblyVersion("0.1.37.16")]
    4.11 +[assembly: AssemblyInformationalVersion("0.1.37.16 Alpha")]
    4.12 \ No newline at end of file