Added core and bus clock readings for AMD's K8 (0F) family of CPUs
authorpaulwerelds
Tue, 21 Sep 2010 09:12:32 +0000
changeset 192ad190510cddd
parent 191 6545fa3ae298
child 193 52ef1cf6b8e5
Added core and bus clock readings for AMD's K8 (0F) family of CPUs
Hardware/CPU/AMD0FCPU.cs
     1.1 --- a/Hardware/CPU/AMD0FCPU.cs	Mon Sep 20 19:28:25 2010 +0000
     1.2 +++ b/Hardware/CPU/AMD0FCPU.cs	Tue Sep 21 09:12:32 2010 +0000
     1.3 @@ -35,14 +35,20 @@
     1.4   
     1.5  */
     1.6  
     1.7 +using System;
     1.8 +using System.Threading;
     1.9 +
    1.10  namespace OpenHardwareMonitor.Hardware.CPU {
    1.11    internal sealed class AMD0FCPU : GenericCPU {
    1.12  
    1.13      private uint pciAddress;
    1.14 -    private Sensor[] coreTemperatures;    
    1.15 +    private Sensor[] coreTemperatures;
    1.16 +    private Sensor[] coreClocks;
    1.17 +    private Sensor busClock;
    1.18  
    1.19      private const ushort PCI_AMD_VENDOR_ID = 0x1022;
    1.20      private const ushort PCI_AMD_0FH_MISCELLANEOUS_DEVICE_ID = 0x1103;
    1.21 +    private const uint FIDVID_STATUS = 0xC0010042;
    1.22      private const uint THERMTRIP_STATUS_REGISTER = 0xE4;
    1.23      private const byte THERM_SENSE_CORE_SEL_CPU0 = 0x4;
    1.24      private const byte THERM_SENSE_CORE_SEL_CPU1 = 0x0;
    1.25 @@ -78,6 +84,14 @@
    1.26        pciAddress = WinRing0.FindPciDeviceById(PCI_AMD_VENDOR_ID,
    1.27          PCI_AMD_0FH_MISCELLANEOUS_DEVICE_ID, (byte)processorIndex);
    1.28  
    1.29 +      busClock = new Sensor("Bus Speed", 0, SensorType.Clock, this, settings);
    1.30 +      coreClocks = new Sensor[coreCount];
    1.31 +      for (int i = 0; i < coreClocks.Length; i++) {
    1.32 +        coreClocks[i] = new Sensor(CoreString(i), i + 1, SensorType.Clock, this, settings);
    1.33 +        if (hasTSC)
    1.34 +          ActivateSensor(coreClocks[i]);
    1.35 +      }
    1.36 +
    1.37        Update();                   
    1.38      }
    1.39  
    1.40 @@ -105,6 +119,31 @@
    1.41            }
    1.42          }
    1.43        }
    1.44 +
    1.45 +      if (hasTSC) {
    1.46 +        double newBusClock = 0;
    1.47 +
    1.48 +        for (int i = 0; i < coreClocks.Length; i++) {
    1.49 +          Thread.Sleep(1);
    1.50 +
    1.51 +          coreClocks[i].Value = (float)MaxClock; // Fail-safe value - if the code below fails, we'll use this instead
    1.52 +
    1.53 +          uint eax, edx;
    1.54 +          if (WinRing0.RdmsrTx(FIDVID_STATUS, out eax, out edx, (UIntPtr)(1L << cpuid[i][0].Thread))) {
    1.55 +            // CurrFID can be found in eax bits 0-5, MaxFID in 16-21
    1.56 +            // 8-13 hold StartFID, we don't use that here.
    1.57 +            double curMP = 0.5 * ((eax & 0x3F) + 8);
    1.58 +            double maxMP = 0.5 * ((eax >> 16 & 0x3F) + 8);
    1.59 +            coreClocks[i].Value = (float)(curMP * MaxClock / maxMP);
    1.60 +            newBusClock = (float)(MaxClock / maxMP);
    1.61 +          }
    1.62 +        }
    1.63 +
    1.64 +        if (newBusClock > 0) {
    1.65 +          this.busClock.Value = (float)newBusClock;
    1.66 +          ActivateSensor(this.busClock);
    1.67 +        }
    1.68 +      }
    1.69      }  
    1.70   
    1.71    }