Added support for the Global\\Access_PCI mutex to synchronize the PCI bus access for reading AMD temperature sensors.

This commit is contained in:
Michael Möller 2020-05-18 00:27:39 +02:00
parent e82b9d7da2
commit 0751abb5c5
5 changed files with 129 additions and 73 deletions

View File

@ -4,7 +4,7 @@
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
Copyright (C) 2009-2010 Michael Möller <mmoeller@openhardwaremonitor.org>
Copyright (C) 2009-2020 Michael Möller <mmoeller@openhardwaremonitor.org>
Copyright (C) 2010 Paul Werelds <paul@werelds.net>
*/
@ -102,24 +102,29 @@ namespace OpenHardwareMonitor.Hardware.CPU {
public override void Update() {
base.Update();
if (miscellaneousControlAddress != Ring0.InvalidPciAddress) {
for (uint i = 0; i < coreTemperatures.Length; i++) {
if (Ring0.WritePciConfig(
miscellaneousControlAddress, THERMTRIP_STATUS_REGISTER,
i > 0 ? thermSenseCoreSelCPU1 : thermSenseCoreSelCPU0)) {
uint value;
if (Ring0.ReadPciConfig(
miscellaneousControlAddress, THERMTRIP_STATUS_REGISTER,
out value))
{
coreTemperatures[i].Value = ((value >> 16) & 0xFF) +
coreTemperatures[i].Parameters[0].Value;
ActivateSensor(coreTemperatures[i]);
} else {
DeactivateSensor(coreTemperatures[i]);
if (Ring0.WaitPciBusMutex(10)) {
if (miscellaneousControlAddress != Ring0.InvalidPciAddress) {
for (uint i = 0; i < coreTemperatures.Length; i++) {
if (Ring0.WritePciConfig(
miscellaneousControlAddress, THERMTRIP_STATUS_REGISTER,
i > 0 ? thermSenseCoreSelCPU1 : thermSenseCoreSelCPU0)) {
uint value;
if (Ring0.ReadPciConfig(
miscellaneousControlAddress, THERMTRIP_STATUS_REGISTER,
out value))
{
coreTemperatures[i].Value = ((value >> 16) & 0xFF) +
coreTemperatures[i].Parameters[0].Value;
ActivateSensor(coreTemperatures[i]);
} else {
DeactivateSensor(coreTemperatures[i]);
}
}
}
}
Ring0.ReleasePciBusMutex();
}
if (HasTimeStampCounter) {

View File

@ -311,11 +311,22 @@ namespace OpenHardwareMonitor.Hardware.CPU {
}
private bool ReadSmuRegister(uint address, out uint value) {
if (!Ring0.WritePciConfig(0, 0xB8, address)) {
if (Ring0.WaitPciBusMutex(10)) {
if (!Ring0.WritePciConfig(0, 0xB8, address)) {
value = 0;
Ring0.ReleasePciBusMutex();
return false;
}
var result = Ring0.ReadPciConfig(0, 0xBC, out value);
Ring0.ReleasePciBusMutex();
return result;
} else {
value = 0;
return false;
}
return Ring0.ReadPciConfig(0, 0xBC, out value);
}
public override void Update() {

View File

@ -160,19 +160,24 @@ namespace OpenHardwareMonitor.Hardware.CPU {
CultureInfo.InvariantCulture));
r.AppendLine();
r.AppendLine("SMN Registers");
r.AppendLine();
r.AppendLine(" Register Value");
var registers = GetSmnRegisters();
for (int i = 0; i < registers.Count; i++)
if (ReadSmnRegister(registers[i], out uint value)) {
r.Append(" ");
r.Append(registers[i].ToString("X8", CultureInfo.InvariantCulture));
r.Append(" ");
r.Append(value.ToString("X8", CultureInfo.InvariantCulture));
r.AppendLine();
}
r.AppendLine();
if (Ring0.WaitPciBusMutex(100)) {
r.AppendLine("SMN Registers");
r.AppendLine();
r.AppendLine(" Register Value");
var registers = GetSmnRegisters();
for (int i = 0; i < registers.Count; i++)
if (ReadSmnRegister(registers[i], out uint value)) {
r.Append(" ");
r.Append(registers[i].ToString("X8", CultureInfo.InvariantCulture));
r.Append(" ");
r.Append(value.ToString("X8", CultureInfo.InvariantCulture));
r.AppendLine();
}
r.AppendLine();
Ring0.ReleasePciBusMutex();
}
return r.ToString();
}
@ -195,52 +200,57 @@ namespace OpenHardwareMonitor.Hardware.CPU {
public override void Update() {
base.Update();
uint value;
if (ReadSmnRegister(FAMILY_17H_M01H_THM_TCON_TEMP, out value)) {
float temperature = ((value >> 21) & 0x7FF) / 8.0f;
if ((value & FAMILY_17H_M01H_THM_TCON_TEMP_RANGE_SEL) != 0)
temperature -= 49;
if (Ring0.WaitPciBusMutex(10)) {
if (tctlTemperature != null) {
tctlTemperature.Value = temperature +
tctlTemperature.Parameters[0].Value;
ActivateSensor(tctlTemperature);
uint value;
if (ReadSmnRegister(FAMILY_17H_M01H_THM_TCON_TEMP, out value)) {
float temperature = ((value >> 21) & 0x7FF) / 8.0f;
if ((value & FAMILY_17H_M01H_THM_TCON_TEMP_RANGE_SEL) != 0)
temperature -= 49;
if (tctlTemperature != null) {
tctlTemperature.Value = temperature +
tctlTemperature.Parameters[0].Value;
ActivateSensor(tctlTemperature);
}
temperature -= tctlOffset;
coreTemperature.Value = temperature +
coreTemperature.Parameters[0].Value;
ActivateSensor(coreTemperature);
}
temperature -= tctlOffset;
float maxTemperature = float.MinValue;
int ccdCount = 0;
float ccdTemperatureSum = 0;
for (uint i = 0; i < ccdTemperatures.Length; i++) {
if (ReadSmnRegister(FAMILY_17H_M70H_CCD_TEMP(i), out value)) {
if ((value & FAMILY_17H_M70H_CCD_TEMP_VALID) == 0)
continue;
coreTemperature.Value = temperature +
coreTemperature.Parameters[0].Value;
ActivateSensor(coreTemperature);
}
float temperature = (value & 0x7FF) / 8.0f - 49;
temperature += ccdTemperatures[i].Parameters[0].Value;
float maxTemperature = float.MinValue;
int ccdCount = 0;
float ccdTemperatureSum = 0;
for (uint i = 0; i < ccdTemperatures.Length; i++) {
if (ReadSmnRegister(FAMILY_17H_M70H_CCD_TEMP(i), out value)) {
if ((value & FAMILY_17H_M70H_CCD_TEMP_VALID) == 0)
continue;
if (temperature > maxTemperature)
maxTemperature = temperature;
ccdCount++;
ccdTemperatureSum += temperature;
float temperature = (value & 0x7FF) / 8.0f - 49;
temperature += ccdTemperatures[i].Parameters[0].Value;
if (temperature > maxTemperature)
maxTemperature = temperature;
ccdCount++;
ccdTemperatureSum += temperature;
ccdTemperatures[i].Value = temperature;
ActivateSensor(ccdTemperatures[i]);
ccdTemperatures[i].Value = temperature;
ActivateSensor(ccdTemperatures[i]);
}
}
}
if (ccdCount > 1) {
ccdMaxTemperature.Value = maxTemperature;
ActivateSensor(ccdMaxTemperature);
if (ccdCount > 1) {
ccdMaxTemperature.Value = maxTemperature;
ActivateSensor(ccdMaxTemperature);
ccdAvgTemperature.Value = ccdTemperatureSum / ccdCount;
ActivateSensor(ccdAvgTemperature);
ccdAvgTemperature.Value = ccdTemperatureSum / ccdCount;
ActivateSensor(ccdAvgTemperature);
}
Ring0.ReleasePciBusMutex();
}
if (energyUnitMultiplier != 0 &&

View File

@ -22,6 +22,7 @@ namespace OpenHardwareMonitor.Hardware {
private static KernelDriver driver;
private static string fileName;
private static Mutex isaBusMutex;
private static Mutex pciBusMutex;
private static readonly StringBuilder report = new StringBuilder();
private const uint OLS_TYPE = 40000;
@ -196,12 +197,21 @@ namespace OpenHardwareMonitor.Hardware {
if (!driver.IsOpen)
driver = null;
string mutexName = "Global\\Access_ISABUS.HTP.Method";
string isaMutexName = "Global\\Access_ISABUS.HTP.Method";
try {
isaBusMutex = new Mutex(false, mutexName);
isaBusMutex = new Mutex(false, isaMutexName);
} catch (UnauthorizedAccessException) {
try {
isaBusMutex = Mutex.OpenExisting(mutexName, MutexRights.Synchronize);
isaBusMutex = Mutex.OpenExisting(isaMutexName, MutexRights.Synchronize);
} catch { }
}
string pciMutexName = "Global\\Access_PCI";
try {
pciBusMutex = new Mutex(false, pciMutexName);
} catch (UnauthorizedAccessException) {
try {
pciBusMutex = Mutex.OpenExisting(pciMutexName, MutexRights.Synchronize);
} catch { }
}
}
@ -229,6 +239,11 @@ namespace OpenHardwareMonitor.Hardware {
isaBusMutex = null;
}
if (pciBusMutex != null) {
pciBusMutex.Close();
pciBusMutex = null;
}
// try to delete temporary driver file again if failed during open
if (fileName != null && File.Exists(fileName)) {
try {
@ -266,6 +281,21 @@ namespace OpenHardwareMonitor.Hardware {
isaBusMutex.ReleaseMutex();
}
public static bool WaitPciBusMutex(int millisecondsTimeout) {
if (pciBusMutex == null)
return true;
try {
return pciBusMutex.WaitOne(millisecondsTimeout, false);
} catch (AbandonedMutexException) { return true; }
catch (InvalidOperationException) { return false; }
}
public static void ReleasePciBusMutex() {
if (pciBusMutex == null)
return;
pciBusMutex.ReleaseMutex();
}
public static bool Rdmsr(uint index, out uint eax, out uint edx) {
if (driver == null) {
eax = 0;

View File

@ -10,5 +10,5 @@
using System.Reflection;
[assembly: AssemblyVersion("0.9.3.3")]
[assembly: AssemblyInformationalVersion("0.9.3.3 Alpha")]
[assembly: AssemblyVersion("0.9.3.4")]
[assembly: AssemblyInformationalVersion("0.9.3.4 Alpha")]