A first correction for reading core and bus clocks on AMD family 14h CPUs.
1.1 --- a/Hardware/CPU/AMD10CPU.cs Sat Apr 16 14:49:47 2011 +0000
1.2 +++ b/Hardware/CPU/AMD10CPU.cs Sat Apr 16 19:26:20 2011 +0000
1.3 @@ -62,6 +62,7 @@
1.4 private const ushort FAMILY_11H_MISCELLANEOUS_CONTROL_DEVICE_ID = 0x1303;
1.5 private const ushort FAMILY_14H_MISCELLANEOUS_CONTROL_DEVICE_ID = 0x1703;
1.6 private const uint REPORTED_TEMPERATURE_CONTROL_REGISTER = 0xA4;
1.7 + private const uint CLOCK_POWER_TIMING_CONTROL_0_REGISTER = 0xD4;
1.8
1.9 private readonly uint miscellaneousControlAddress;
1.10 private readonly ushort miscellaneousControlDeviceId;
1.11 @@ -86,7 +87,7 @@
1.12 case 0x11: miscellaneousControlDeviceId =
1.13 FAMILY_11H_MISCELLANEOUS_CONTROL_DEVICE_ID; break;
1.14 case 0x14: miscellaneousControlDeviceId =
1.15 - FAMILY_11H_MISCELLANEOUS_CONTROL_DEVICE_ID; break;
1.16 + FAMILY_14H_MISCELLANEOUS_CONTROL_DEVICE_ID; break;
1.17 default: miscellaneousControlDeviceId = 0; break;
1.18 }
1.19
1.20 @@ -170,7 +171,7 @@
1.21 Ring0.Wrmsr(PERF_CTR_0, 0, 0);
1.22
1.23 long ticks = (long)(timeWindow * Stopwatch.Frequency);
1.24 - uint lsbBegin, msbBegin, lsbEnd, msbEnd;
1.25 + uint lsbBegin, msbBegin, lsbEnd, msbEnd;
1.26
1.27 long timeBegin = Stopwatch.GetTimestamp() +
1.28 (long)Math.Ceiling(0.001 * ticks);
1.29 @@ -181,10 +182,22 @@
1.30 Ring0.Rdmsr(PERF_CTR_0, out lsbEnd, out msbEnd);
1.31
1.32 Ring0.Rdmsr(COFVID_STATUS, out eax, out edx);
1.33 - uint cpuDid = (eax >> 6) & 7;
1.34 - uint cpuFid = eax & 0x1F;
1.35 - double coreMultiplier = MultiplierFromIDs(cpuDid, cpuFid);
1.36 + double coreMultiplier;
1.37 + if (family == 0x14) {
1.38 + uint divisorIdMSD = (eax >> 4) & 0x1F;
1.39 + uint divisorIdLSD = eax & 0xF;
1.40 + uint value = 0;
1.41 + Ring0.ReadPciConfig(miscellaneousControlAddress,
1.42 + CLOCK_POWER_TIMING_CONTROL_0_REGISTER, out value);
1.43 + uint frequencyId = value & 0x1F;
1.44
1.45 + coreMultiplier =
1.46 + MultiplierFromIDs(divisorIdMSD, divisorIdLSD, frequencyId);
1.47 + } else {
1.48 + uint cpuDid = (eax >> 6) & 7;
1.49 + uint cpuFid = eax & 0x1F;
1.50 + coreMultiplier = MultiplierFromIDs(cpuDid, cpuFid);
1.51 + }
1.52 ulong countBegin = ((ulong)msbBegin << 32) | lsbBegin;
1.53 ulong countEnd = ((ulong)msbEnd << 32) | lsbEnd;
1.54
1.55 @@ -193,7 +206,7 @@
1.56 (timeEnd - timeBegin);
1.57
1.58 double busFrequency = coreFrequency / coreMultiplier;
1.59 - return 0.5 * Math.Round(2 * TimeStampCounterFrequency / busFrequency);
1.60 + return 0.25 * Math.Round(4 * TimeStampCounterFrequency / busFrequency);
1.61 }
1.62
1.63 protected override uint[] GetMSRs() {
1.64 @@ -210,15 +223,30 @@
1.65 r.Append("Time Stamp Counter Multiplier: ");
1.66 r.AppendLine(timeStampCounterMultiplier.ToString(
1.67 CultureInfo.InvariantCulture));
1.68 + if (family == 0x14) {
1.69 + uint value = 0;
1.70 + Ring0.ReadPciConfig(miscellaneousControlAddress,
1.71 + CLOCK_POWER_TIMING_CONTROL_0_REGISTER, out value);
1.72 + r.Append("PCI Register D18F3xD4: ");
1.73 + r.AppendLine(value.ToString("X8", CultureInfo.InvariantCulture));
1.74 + }
1.75 r.AppendLine();
1.76
1.77 return r.ToString();
1.78 }
1.79
1.80 + // calculate the multiplier for family 10h based on Did and Fid
1.81 private static double MultiplierFromIDs(uint divisorID, uint frequencyID) {
1.82 return 0.5 * (frequencyID + 0x10) / (1 << (int)divisorID);
1.83 }
1.84
1.85 + // calculate the multiplier for family 14h based on DidMSD, DidLSD and Fid
1.86 + private static double MultiplierFromIDs(uint divisorIdMSD,
1.87 + uint divisorIdLSD, uint frequencyId)
1.88 + {
1.89 + return (frequencyId + 0x10) / (divisorIdMSD + (divisorIdLSD * 0.25) + 1);
1.90 + }
1.91 +
1.92 private string ReadFirstLine(Stream stream) {
1.93 StringBuilder sb = new StringBuilder();
1.94 try {
1.95 @@ -268,11 +296,23 @@
1.96 if (Ring0.RdmsrTx(COFVID_STATUS, out curEax, out curEdx,
1.97 1UL << cpuid[i][0].Thread))
1.98 {
1.99 - // 8:6 CpuDid: current core divisor ID
1.100 - // 5:0 CpuFid: current core frequency ID
1.101 - uint cpuDid = (curEax >> 6) & 7;
1.102 - uint cpuFid = curEax & 0x1F;
1.103 - double multiplier = MultiplierFromIDs(cpuDid, cpuFid);
1.104 + double multiplier;
1.105 + if (family == 0x14) {
1.106 + uint divisorIdMSD = (curEax >> 4) & 0x1F;
1.107 + uint divisorIdLSD = curEax & 0xF;
1.108 + uint value = 0;
1.109 + Ring0.ReadPciConfig(miscellaneousControlAddress,
1.110 + CLOCK_POWER_TIMING_CONTROL_0_REGISTER, out value);
1.111 + uint frequencyId = value & 0x1F;
1.112 + multiplier =
1.113 + MultiplierFromIDs(divisorIdMSD, divisorIdLSD, frequencyId);
1.114 + } else {
1.115 + // 8:6 CpuDid: current core divisor ID
1.116 + // 5:0 CpuFid: current core frequency ID
1.117 + uint cpuDid = (curEax >> 6) & 7;
1.118 + uint cpuFid = curEax & 0x1F;
1.119 + multiplier = MultiplierFromIDs(cpuDid, cpuFid);
1.120 + }
1.121
1.122 coreClocks[i].Value =
1.123 (float)(multiplier * TimeStampCounterFrequency /
2.1 --- a/Properties/AssemblyVersion.cs Sat Apr 16 14:49:47 2011 +0000
2.2 +++ b/Properties/AssemblyVersion.cs Sat Apr 16 19:26:20 2011 +0000
2.3 @@ -37,5 +37,5 @@
2.4
2.5 using System.Reflection;
2.6
2.7 -[assembly: AssemblyVersion("0.2.1.20")]
2.8 -[assembly: AssemblyInformationalVersion("0.2.1.20 Alpha")]
2.9 \ No newline at end of file
2.10 +[assembly: AssemblyVersion("0.2.1.22")]
2.11 +[assembly: AssemblyInformationalVersion("0.2.1.22 Alpha")]
2.12 \ No newline at end of file