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 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/. 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> Copyright (C) 2010 Paul Werelds <paul@werelds.net>
*/ */
@ -102,24 +102,29 @@ namespace OpenHardwareMonitor.Hardware.CPU {
public override void Update() { public override void Update() {
base.Update(); base.Update();
if (miscellaneousControlAddress != Ring0.InvalidPciAddress) { if (Ring0.WaitPciBusMutex(10)) {
for (uint i = 0; i < coreTemperatures.Length; i++) {
if (Ring0.WritePciConfig( if (miscellaneousControlAddress != Ring0.InvalidPciAddress) {
miscellaneousControlAddress, THERMTRIP_STATUS_REGISTER, for (uint i = 0; i < coreTemperatures.Length; i++) {
i > 0 ? thermSenseCoreSelCPU1 : thermSenseCoreSelCPU0)) { if (Ring0.WritePciConfig(
uint value; miscellaneousControlAddress, THERMTRIP_STATUS_REGISTER,
if (Ring0.ReadPciConfig( i > 0 ? thermSenseCoreSelCPU1 : thermSenseCoreSelCPU0)) {
miscellaneousControlAddress, THERMTRIP_STATUS_REGISTER, uint value;
out value)) if (Ring0.ReadPciConfig(
{ miscellaneousControlAddress, THERMTRIP_STATUS_REGISTER,
coreTemperatures[i].Value = ((value >> 16) & 0xFF) + out value))
coreTemperatures[i].Parameters[0].Value; {
ActivateSensor(coreTemperatures[i]); coreTemperatures[i].Value = ((value >> 16) & 0xFF) +
} else { coreTemperatures[i].Parameters[0].Value;
DeactivateSensor(coreTemperatures[i]); ActivateSensor(coreTemperatures[i]);
} else {
DeactivateSensor(coreTemperatures[i]);
}
} }
} }
} }
Ring0.ReleasePciBusMutex();
} }
if (HasTimeStampCounter) { if (HasTimeStampCounter) {

View File

@ -311,11 +311,22 @@ namespace OpenHardwareMonitor.Hardware.CPU {
} }
private bool ReadSmuRegister(uint address, out uint value) { 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; value = 0;
return false; return false;
} }
return Ring0.ReadPciConfig(0, 0xBC, out value);
} }
public override void Update() { public override void Update() {

View File

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

View File

@ -22,6 +22,7 @@ namespace OpenHardwareMonitor.Hardware {
private static KernelDriver driver; private static KernelDriver driver;
private static string fileName; private static string fileName;
private static Mutex isaBusMutex; private static Mutex isaBusMutex;
private static Mutex pciBusMutex;
private static readonly StringBuilder report = new StringBuilder(); private static readonly StringBuilder report = new StringBuilder();
private const uint OLS_TYPE = 40000; private const uint OLS_TYPE = 40000;
@ -196,12 +197,21 @@ namespace OpenHardwareMonitor.Hardware {
if (!driver.IsOpen) if (!driver.IsOpen)
driver = null; driver = null;
string mutexName = "Global\\Access_ISABUS.HTP.Method"; string isaMutexName = "Global\\Access_ISABUS.HTP.Method";
try { try {
isaBusMutex = new Mutex(false, mutexName); isaBusMutex = new Mutex(false, isaMutexName);
} catch (UnauthorizedAccessException) { } catch (UnauthorizedAccessException) {
try { 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 { } } catch { }
} }
} }
@ -229,6 +239,11 @@ namespace OpenHardwareMonitor.Hardware {
isaBusMutex = null; isaBusMutex = null;
} }
if (pciBusMutex != null) {
pciBusMutex.Close();
pciBusMutex = null;
}
// try to delete temporary driver file again if failed during open // try to delete temporary driver file again if failed during open
if (fileName != null && File.Exists(fileName)) { if (fileName != null && File.Exists(fileName)) {
try { try {
@ -266,6 +281,21 @@ namespace OpenHardwareMonitor.Hardware {
isaBusMutex.ReleaseMutex(); 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) { public static bool Rdmsr(uint index, out uint eax, out uint edx) {
if (driver == null) { if (driver == null) {
eax = 0; eax = 0;

View File

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