# HG changeset patch # User moel.mich # Date 1285182732 0 # Node ID 5e9a8595296c80ac445f5868ff56e53f124be606 # Parent 0ee888c485d5019ea8e48d5394f4917b7a01be0f Rewritten the PCI access for AMD CPUs. diff -r 0ee888c485d5 -r 5e9a8595296c Hardware/CPU/AMD0FCPU.cs --- a/Hardware/CPU/AMD0FCPU.cs Tue Sep 21 20:32:36 2010 +0000 +++ b/Hardware/CPU/AMD0FCPU.cs Wed Sep 22 19:12:12 2010 +0000 @@ -36,23 +36,27 @@ */ using System; +using System.Globalization; +using System.Text; using System.Threading; namespace OpenHardwareMonitor.Hardware.CPU { - internal sealed class AMD0FCPU : GenericCPU { - - private readonly uint pciAddress; + internal sealed class AMD0FCPU : AMDCPU { + private readonly Sensor[] coreTemperatures; private readonly Sensor[] coreClocks; private readonly Sensor busClock; - private const ushort PCI_AMD_VENDOR_ID = 0x1022; - private const ushort PCI_AMD_0FH_MISCELLANEOUS_DEVICE_ID = 0x1103; private const uint FIDVID_STATUS = 0xC0010042; + + private const byte MISCELLANEOUS_CONTROL_FUNCTION = 3; + private const ushort MISCELLANEOUS_CONTROL_DEVICE_ID = 0x1103; private const uint THERMTRIP_STATUS_REGISTER = 0xE4; private const byte THERM_SENSE_CORE_SEL_CPU0 = 0x4; private const byte THERM_SENSE_CORE_SEL_CPU1 = 0x0; + private readonly uint miscellaneousControlAddress; + public AMD0FCPU(int processorIndex, CPUID[][] cpuid, ISettings settings) : base(processorIndex, cpuid, settings) { @@ -80,8 +84,8 @@ coreTemperatures = new Sensor[0]; } - pciAddress = WinRing0.FindPciDeviceById(PCI_AMD_VENDOR_ID, - PCI_AMD_0FH_MISCELLANEOUS_DEVICE_ID, (byte)processorIndex); + miscellaneousControlAddress = GetPciAddress( + MISCELLANEOUS_CONTROL_FUNCTION, MISCELLANEOUS_CONTROL_DEVICE_ID); busClock = new Sensor("Bus Speed", 0, SensorType.Clock, this, settings); coreClocks = new Sensor[coreCount]; @@ -99,17 +103,31 @@ return new [] { FIDVID_STATUS }; } + public override string GetReport() { + StringBuilder r = new StringBuilder(); + r.Append(base.GetReport()); + + r.Append("Miscellaneous Control Address: "); + r.AppendLine((miscellaneousControlAddress).ToString("X", + CultureInfo.InvariantCulture)); + r.AppendLine(); + + return r.ToString(); + } + public override void Update() { base.Update(); - if (pciAddress != 0xFFFFFFFF) { + if (miscellaneousControlAddress != WinRing0.InvalidPciAddress) { for (uint i = 0; i < coreTemperatures.Length; i++) { if (WinRing0.WritePciConfigDwordEx( - pciAddress, THERMTRIP_STATUS_REGISTER, + miscellaneousControlAddress, THERMTRIP_STATUS_REGISTER, i > 0 ? THERM_SENSE_CORE_SEL_CPU1 : THERM_SENSE_CORE_SEL_CPU0)) { uint value; if (WinRing0.ReadPciConfigDwordEx( - pciAddress, THERMTRIP_STATUS_REGISTER, out value)) { + miscellaneousControlAddress, THERMTRIP_STATUS_REGISTER, + out value)) + { coreTemperatures[i].Value = ((value >> 16) & 0xFF) + coreTemperatures[i].Parameters[0].Value; ActivateSensor(coreTemperatures[i]); diff -r 0ee888c485d5 -r 5e9a8595296c Hardware/CPU/AMD10CPU.cs --- a/Hardware/CPU/AMD10CPU.cs Tue Sep 21 20:32:36 2010 +0000 +++ b/Hardware/CPU/AMD10CPU.cs Wed Sep 22 19:12:12 2010 +0000 @@ -35,22 +35,25 @@ */ +using System; +using System.Globalization; +using System.Text; + namespace OpenHardwareMonitor.Hardware.CPU { - internal sealed class AMD10CPU : GenericCPU { - - private readonly uint pciAddress; + internal sealed class AMD10CPU : AMDCPU { private readonly Sensor coreTemperature; - private const ushort PCI_AMD_VENDOR_ID = 0x1022; - private const ushort PCI_AMD_10H_MISCELLANEOUS_DEVICE_ID = 0x1203; - private const ushort PCI_AMD_11H_MISCELLANEOUS_DEVICE_ID = 0x1303; - private const uint REPORTED_TEMPERATURE_CONTROL_REGISTER = 0xA4; + private const byte MISCELLANEOUS_CONTROL_FUNCTION = 3; + private const ushort MISCELLANEOUS_CONTROL_DEVICE_ID = 0x1203; + private const byte REPORTED_TEMPERATURE_CONTROL_REGISTER = 0xA4; + + private readonly uint miscellaneousControlAddress; public AMD10CPU(int processorIndex, CPUID[][] cpuid, ISettings settings) : base(processorIndex, cpuid, settings) - { + { // AMD family 10h processors support only one temperature sensor coreTemperature = new Sensor( "Core" + (coreCount > 1 ? " #1 - #" + coreCount : ""), 0, @@ -58,11 +61,9 @@ new ParameterDescription("Offset [°C]", "Temperature offset.", 0) }, settings); - pciAddress = WinRing0.FindPciDeviceById(PCI_AMD_VENDOR_ID, - PCI_AMD_10H_MISCELLANEOUS_DEVICE_ID, (byte)processorIndex); - if (pciAddress == 0xFFFFFFFF) - pciAddress = WinRing0.FindPciDeviceById(PCI_AMD_VENDOR_ID, - PCI_AMD_11H_MISCELLANEOUS_DEVICE_ID, (byte)processorIndex); + // get the pci address for the Miscellaneous Control registers + miscellaneousControlAddress = GetPciAddress( + MISCELLANEOUS_CONTROL_FUNCTION, MISCELLANEOUS_CONTROL_DEVICE_ID); Update(); } @@ -71,12 +72,24 @@ return new uint[] { }; } + public override string GetReport() { + StringBuilder r = new StringBuilder(); + r.Append(base.GetReport()); + + r.Append("Miscellaneous Control Address: "); + r.AppendLine((miscellaneousControlAddress).ToString("X", + CultureInfo.InvariantCulture)); + r.AppendLine(); + + return r.ToString(); + } + public override void Update() { base.Update(); - if (pciAddress != 0xFFFFFFFF) { + if (miscellaneousControlAddress != WinRing0.InvalidPciAddress) { uint value; - if (WinRing0.ReadPciConfigDwordEx(pciAddress, + if (WinRing0.ReadPciConfigDwordEx(miscellaneousControlAddress, REPORTED_TEMPERATURE_CONTROL_REGISTER, out value)) { coreTemperature.Value = ((value >> 21) & 0x7FF) / 8.0f + coreTemperature.Parameters[0].Value; diff -r 0ee888c485d5 -r 5e9a8595296c Hardware/CPU/AMDCPU.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Hardware/CPU/AMDCPU.cs Wed Sep 22 19:12:12 2010 +0000 @@ -0,0 +1,66 @@ +/* + + Version: MPL 1.1/GPL 2.0/LGPL 2.1 + + The contents of this file are subject to the Mozilla Public License Version + 1.1 (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" basis, + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + for the specific language governing rights and limitations under the License. + + The Original Code is the Open Hardware Monitor code. + + The Initial Developer of the Original Code is + Michael Möller . + Portions created by the Initial Developer are Copyright (C) 2009-2010 + the Initial Developer. All Rights Reserved. + + Contributor(s): + + Alternatively, the contents of this file may be used under the terms of + either the GNU General Public License Version 2 or later (the "GPL"), or + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + in which case the provisions of the GPL or the LGPL are applicable instead + of those above. If you wish to allow use of your version of this file only + under the terms of either the GPL or the LGPL, and not to allow others to + use your version of this file under the terms of the MPL, indicate your + decision by deleting the provisions above and replace them with the notice + and other provisions required by the GPL or the LGPL. If you do not delete + the provisions above, a recipient may use your version of this file under + the terms of any one of the MPL, the GPL or the LGPL. + +*/ + +namespace OpenHardwareMonitor.Hardware.CPU { + + internal abstract class AMDCPU : GenericCPU { + + private const byte PCI_BUS = 0; + private const byte PCI_BASE_DEVICE = 24; + private const byte DEVICE_VENDOR_ID_REGISTER = 0; + private const ushort AMD_VENDOR_ID = 0x1022; + + public AMDCPU(int processorIndex, CPUID[][] cpuid, ISettings settings) + : base(processorIndex, cpuid, settings) { } + + protected uint GetPciAddress(byte function, ushort deviceId) { + uint address = WinRing0.GetPciAddress(PCI_BUS, + (byte)(PCI_BASE_DEVICE + processorIndex), function); + + uint deviceVendor; + if (!WinRing0.ReadPciConfigDwordEx( + address, DEVICE_VENDOR_ID_REGISTER, out deviceVendor)) + return WinRing0.InvalidPciAddress; + + if (deviceVendor != (deviceId << 16 | AMD_VENDOR_ID)) + return WinRing0.InvalidPciAddress; + + return address; + } + + } +} diff -r 0ee888c485d5 -r 5e9a8595296c Hardware/WinRing0.cs --- a/Hardware/WinRing0.cs Tue Sep 21 20:32:36 2010 +0000 +++ b/Hardware/WinRing0.cs Wed Sep 22 19:12:12 2010 +0000 @@ -87,8 +87,6 @@ UIntPtr threadAffinityMask); public delegate byte ReadIoPortByteDelegate(ushort port); public delegate void WriteIoPortByteDelegate(ushort port, byte value); - public delegate uint FindPciDeviceByIdDelegate(ushort vendorId, - ushort deviceId, byte index); public delegate bool ReadPciConfigDwordExDelegate(uint pciAddress, uint regAddress, out uint value); public delegate bool WritePciConfigDwordExDelegate(uint pciAddress, @@ -114,8 +112,6 @@ CreateDelegate("ReadIoPortByte"); public static readonly WriteIoPortByteDelegate WriteIoPortByte = CreateDelegate("WriteIoPortByte"); - public static readonly FindPciDeviceByIdDelegate FindPciDeviceById = - CreateDelegate("FindPciDeviceById"); public static readonly ReadPciConfigDwordExDelegate ReadPciConfigDwordEx = CreateDelegate("ReadPciConfigDwordEx"); public static readonly WritePciConfigDwordExDelegate WritePciConfigDwordEx = @@ -164,6 +160,13 @@ public static void ReleaseIsaBusMutex() { isaBusMutex.ReleaseMutex(); - } + } + + public const uint InvalidPciAddress = 0xFFFFFFFF; + + public static uint GetPciAddress(byte bus, byte device, byte function) { + return + (uint)(((bus & 0xFF) << 8) | ((device & 0x1F) << 3) | (function & 7)); + } } } diff -r 0ee888c485d5 -r 5e9a8595296c OpenHardwareMonitorLib.csproj --- a/OpenHardwareMonitorLib.csproj Tue Sep 21 20:32:36 2010 +0000 +++ b/OpenHardwareMonitorLib.csproj Wed Sep 22 19:12:12 2010 +0000 @@ -61,6 +61,7 @@ +