Rewritten the PCI access for AMD CPUs.
1.1 --- a/Hardware/CPU/AMD0FCPU.cs Tue Sep 21 20:32:36 2010 +0000
1.2 +++ b/Hardware/CPU/AMD0FCPU.cs Wed Sep 22 19:12:12 2010 +0000
1.3 @@ -36,23 +36,27 @@
1.4 */
1.5
1.6 using System;
1.7 +using System.Globalization;
1.8 +using System.Text;
1.9 using System.Threading;
1.10
1.11 namespace OpenHardwareMonitor.Hardware.CPU {
1.12 - internal sealed class AMD0FCPU : GenericCPU {
1.13 -
1.14 - private readonly uint pciAddress;
1.15 + internal sealed class AMD0FCPU : AMDCPU {
1.16 +
1.17 private readonly Sensor[] coreTemperatures;
1.18 private readonly Sensor[] coreClocks;
1.19 private readonly Sensor busClock;
1.20
1.21 - private const ushort PCI_AMD_VENDOR_ID = 0x1022;
1.22 - private const ushort PCI_AMD_0FH_MISCELLANEOUS_DEVICE_ID = 0x1103;
1.23 private const uint FIDVID_STATUS = 0xC0010042;
1.24 +
1.25 + private const byte MISCELLANEOUS_CONTROL_FUNCTION = 3;
1.26 + private const ushort MISCELLANEOUS_CONTROL_DEVICE_ID = 0x1103;
1.27 private const uint THERMTRIP_STATUS_REGISTER = 0xE4;
1.28 private const byte THERM_SENSE_CORE_SEL_CPU0 = 0x4;
1.29 private const byte THERM_SENSE_CORE_SEL_CPU1 = 0x0;
1.30
1.31 + private readonly uint miscellaneousControlAddress;
1.32 +
1.33 public AMD0FCPU(int processorIndex, CPUID[][] cpuid, ISettings settings)
1.34 : base(processorIndex, cpuid, settings)
1.35 {
1.36 @@ -80,8 +84,8 @@
1.37 coreTemperatures = new Sensor[0];
1.38 }
1.39
1.40 - pciAddress = WinRing0.FindPciDeviceById(PCI_AMD_VENDOR_ID,
1.41 - PCI_AMD_0FH_MISCELLANEOUS_DEVICE_ID, (byte)processorIndex);
1.42 + miscellaneousControlAddress = GetPciAddress(
1.43 + MISCELLANEOUS_CONTROL_FUNCTION, MISCELLANEOUS_CONTROL_DEVICE_ID);
1.44
1.45 busClock = new Sensor("Bus Speed", 0, SensorType.Clock, this, settings);
1.46 coreClocks = new Sensor[coreCount];
1.47 @@ -99,17 +103,31 @@
1.48 return new [] { FIDVID_STATUS };
1.49 }
1.50
1.51 + public override string GetReport() {
1.52 + StringBuilder r = new StringBuilder();
1.53 + r.Append(base.GetReport());
1.54 +
1.55 + r.Append("Miscellaneous Control Address: ");
1.56 + r.AppendLine((miscellaneousControlAddress).ToString("X",
1.57 + CultureInfo.InvariantCulture));
1.58 + r.AppendLine();
1.59 +
1.60 + return r.ToString();
1.61 + }
1.62 +
1.63 public override void Update() {
1.64 base.Update();
1.65
1.66 - if (pciAddress != 0xFFFFFFFF) {
1.67 + if (miscellaneousControlAddress != WinRing0.InvalidPciAddress) {
1.68 for (uint i = 0; i < coreTemperatures.Length; i++) {
1.69 if (WinRing0.WritePciConfigDwordEx(
1.70 - pciAddress, THERMTRIP_STATUS_REGISTER,
1.71 + miscellaneousControlAddress, THERMTRIP_STATUS_REGISTER,
1.72 i > 0 ? THERM_SENSE_CORE_SEL_CPU1 : THERM_SENSE_CORE_SEL_CPU0)) {
1.73 uint value;
1.74 if (WinRing0.ReadPciConfigDwordEx(
1.75 - pciAddress, THERMTRIP_STATUS_REGISTER, out value)) {
1.76 + miscellaneousControlAddress, THERMTRIP_STATUS_REGISTER,
1.77 + out value))
1.78 + {
1.79 coreTemperatures[i].Value = ((value >> 16) & 0xFF) +
1.80 coreTemperatures[i].Parameters[0].Value;
1.81 ActivateSensor(coreTemperatures[i]);
2.1 --- a/Hardware/CPU/AMD10CPU.cs Tue Sep 21 20:32:36 2010 +0000
2.2 +++ b/Hardware/CPU/AMD10CPU.cs Wed Sep 22 19:12:12 2010 +0000
2.3 @@ -35,22 +35,25 @@
2.4
2.5 */
2.6
2.7 +using System;
2.8 +using System.Globalization;
2.9 +using System.Text;
2.10 +
2.11 namespace OpenHardwareMonitor.Hardware.CPU {
2.12
2.13 - internal sealed class AMD10CPU : GenericCPU {
2.14 -
2.15 - private readonly uint pciAddress;
2.16 + internal sealed class AMD10CPU : AMDCPU {
2.17
2.18 private readonly Sensor coreTemperature;
2.19
2.20 - private const ushort PCI_AMD_VENDOR_ID = 0x1022;
2.21 - private const ushort PCI_AMD_10H_MISCELLANEOUS_DEVICE_ID = 0x1203;
2.22 - private const ushort PCI_AMD_11H_MISCELLANEOUS_DEVICE_ID = 0x1303;
2.23 - private const uint REPORTED_TEMPERATURE_CONTROL_REGISTER = 0xA4;
2.24 + private const byte MISCELLANEOUS_CONTROL_FUNCTION = 3;
2.25 + private const ushort MISCELLANEOUS_CONTROL_DEVICE_ID = 0x1203;
2.26 + private const byte REPORTED_TEMPERATURE_CONTROL_REGISTER = 0xA4;
2.27 +
2.28 + private readonly uint miscellaneousControlAddress;
2.29
2.30 public AMD10CPU(int processorIndex, CPUID[][] cpuid, ISettings settings)
2.31 : base(processorIndex, cpuid, settings)
2.32 - {
2.33 + {
2.34 // AMD family 10h processors support only one temperature sensor
2.35 coreTemperature = new Sensor(
2.36 "Core" + (coreCount > 1 ? " #1 - #" + coreCount : ""), 0,
2.37 @@ -58,11 +61,9 @@
2.38 new ParameterDescription("Offset [°C]", "Temperature offset.", 0)
2.39 }, settings);
2.40
2.41 - pciAddress = WinRing0.FindPciDeviceById(PCI_AMD_VENDOR_ID,
2.42 - PCI_AMD_10H_MISCELLANEOUS_DEVICE_ID, (byte)processorIndex);
2.43 - if (pciAddress == 0xFFFFFFFF)
2.44 - pciAddress = WinRing0.FindPciDeviceById(PCI_AMD_VENDOR_ID,
2.45 - PCI_AMD_11H_MISCELLANEOUS_DEVICE_ID, (byte)processorIndex);
2.46 + // get the pci address for the Miscellaneous Control registers
2.47 + miscellaneousControlAddress = GetPciAddress(
2.48 + MISCELLANEOUS_CONTROL_FUNCTION, MISCELLANEOUS_CONTROL_DEVICE_ID);
2.49
2.50 Update();
2.51 }
2.52 @@ -71,12 +72,24 @@
2.53 return new uint[] { };
2.54 }
2.55
2.56 + public override string GetReport() {
2.57 + StringBuilder r = new StringBuilder();
2.58 + r.Append(base.GetReport());
2.59 +
2.60 + r.Append("Miscellaneous Control Address: ");
2.61 + r.AppendLine((miscellaneousControlAddress).ToString("X",
2.62 + CultureInfo.InvariantCulture));
2.63 + r.AppendLine();
2.64 +
2.65 + return r.ToString();
2.66 + }
2.67 +
2.68 public override void Update() {
2.69 base.Update();
2.70
2.71 - if (pciAddress != 0xFFFFFFFF) {
2.72 + if (miscellaneousControlAddress != WinRing0.InvalidPciAddress) {
2.73 uint value;
2.74 - if (WinRing0.ReadPciConfigDwordEx(pciAddress,
2.75 + if (WinRing0.ReadPciConfigDwordEx(miscellaneousControlAddress,
2.76 REPORTED_TEMPERATURE_CONTROL_REGISTER, out value)) {
2.77 coreTemperature.Value = ((value >> 21) & 0x7FF) / 8.0f +
2.78 coreTemperature.Parameters[0].Value;
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/Hardware/CPU/AMDCPU.cs Wed Sep 22 19:12:12 2010 +0000
3.3 @@ -0,0 +1,66 @@
3.4 +/*
3.5 +
3.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
3.7 +
3.8 + The contents of this file are subject to the Mozilla Public License Version
3.9 + 1.1 (the "License"); you may not use this file except in compliance with
3.10 + the License. You may obtain a copy of the License at
3.11 +
3.12 + http://www.mozilla.org/MPL/
3.13 +
3.14 + Software distributed under the License is distributed on an "AS IS" basis,
3.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
3.16 + for the specific language governing rights and limitations under the License.
3.17 +
3.18 + The Original Code is the Open Hardware Monitor code.
3.19 +
3.20 + The Initial Developer of the Original Code is
3.21 + Michael Möller <m.moeller@gmx.ch>.
3.22 + Portions created by the Initial Developer are Copyright (C) 2009-2010
3.23 + the Initial Developer. All Rights Reserved.
3.24 +
3.25 + Contributor(s):
3.26 +
3.27 + Alternatively, the contents of this file may be used under the terms of
3.28 + either the GNU General Public License Version 2 or later (the "GPL"), or
3.29 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
3.30 + in which case the provisions of the GPL or the LGPL are applicable instead
3.31 + of those above. If you wish to allow use of your version of this file only
3.32 + under the terms of either the GPL or the LGPL, and not to allow others to
3.33 + use your version of this file under the terms of the MPL, indicate your
3.34 + decision by deleting the provisions above and replace them with the notice
3.35 + and other provisions required by the GPL or the LGPL. If you do not delete
3.36 + the provisions above, a recipient may use your version of this file under
3.37 + the terms of any one of the MPL, the GPL or the LGPL.
3.38 +
3.39 +*/
3.40 +
3.41 +namespace OpenHardwareMonitor.Hardware.CPU {
3.42 +
3.43 + internal abstract class AMDCPU : GenericCPU {
3.44 +
3.45 + private const byte PCI_BUS = 0;
3.46 + private const byte PCI_BASE_DEVICE = 24;
3.47 + private const byte DEVICE_VENDOR_ID_REGISTER = 0;
3.48 + private const ushort AMD_VENDOR_ID = 0x1022;
3.49 +
3.50 + public AMDCPU(int processorIndex, CPUID[][] cpuid, ISettings settings)
3.51 + : base(processorIndex, cpuid, settings) { }
3.52 +
3.53 + protected uint GetPciAddress(byte function, ushort deviceId) {
3.54 + uint address = WinRing0.GetPciAddress(PCI_BUS,
3.55 + (byte)(PCI_BASE_DEVICE + processorIndex), function);
3.56 +
3.57 + uint deviceVendor;
3.58 + if (!WinRing0.ReadPciConfigDwordEx(
3.59 + address, DEVICE_VENDOR_ID_REGISTER, out deviceVendor))
3.60 + return WinRing0.InvalidPciAddress;
3.61 +
3.62 + if (deviceVendor != (deviceId << 16 | AMD_VENDOR_ID))
3.63 + return WinRing0.InvalidPciAddress;
3.64 +
3.65 + return address;
3.66 + }
3.67 +
3.68 + }
3.69 +}
4.1 --- a/Hardware/WinRing0.cs Tue Sep 21 20:32:36 2010 +0000
4.2 +++ b/Hardware/WinRing0.cs Wed Sep 22 19:12:12 2010 +0000
4.3 @@ -87,8 +87,6 @@
4.4 UIntPtr threadAffinityMask);
4.5 public delegate byte ReadIoPortByteDelegate(ushort port);
4.6 public delegate void WriteIoPortByteDelegate(ushort port, byte value);
4.7 - public delegate uint FindPciDeviceByIdDelegate(ushort vendorId,
4.8 - ushort deviceId, byte index);
4.9 public delegate bool ReadPciConfigDwordExDelegate(uint pciAddress,
4.10 uint regAddress, out uint value);
4.11 public delegate bool WritePciConfigDwordExDelegate(uint pciAddress,
4.12 @@ -114,8 +112,6 @@
4.13 CreateDelegate<ReadIoPortByteDelegate>("ReadIoPortByte");
4.14 public static readonly WriteIoPortByteDelegate WriteIoPortByte =
4.15 CreateDelegate<WriteIoPortByteDelegate>("WriteIoPortByte");
4.16 - public static readonly FindPciDeviceByIdDelegate FindPciDeviceById =
4.17 - CreateDelegate<FindPciDeviceByIdDelegate>("FindPciDeviceById");
4.18 public static readonly ReadPciConfigDwordExDelegate ReadPciConfigDwordEx =
4.19 CreateDelegate<ReadPciConfigDwordExDelegate>("ReadPciConfigDwordEx");
4.20 public static readonly WritePciConfigDwordExDelegate WritePciConfigDwordEx =
4.21 @@ -164,6 +160,13 @@
4.22
4.23 public static void ReleaseIsaBusMutex() {
4.24 isaBusMutex.ReleaseMutex();
4.25 - }
4.26 + }
4.27 +
4.28 + public const uint InvalidPciAddress = 0xFFFFFFFF;
4.29 +
4.30 + public static uint GetPciAddress(byte bus, byte device, byte function) {
4.31 + return
4.32 + (uint)(((bus & 0xFF) << 8) | ((device & 0x1F) << 3) | (function & 7));
4.33 + }
4.34 }
4.35 }
5.1 --- a/OpenHardwareMonitorLib.csproj Tue Sep 21 20:32:36 2010 +0000
5.2 +++ b/OpenHardwareMonitorLib.csproj Wed Sep 22 19:12:12 2010 +0000
5.3 @@ -61,6 +61,7 @@
5.4 <Compile Include="Hardware\ATI\ATIGPU.cs" />
5.5 <Compile Include="Hardware\ATI\ATIGroup.cs" />
5.6 <Compile Include="Hardware\Computer.cs" />
5.7 + <Compile Include="Hardware\CPU\AMDCPU.cs" />
5.8 <Compile Include="Hardware\CPU\GenericCPU.cs" />
5.9 <Compile Include="Hardware\CPU\AMD0FCPU.cs" />
5.10 <Compile Include="Hardware\CPU\AMD10CPU.cs" />