From bb65e069fd1fbe04bae7ee9f9749932b8c91b7e9 Mon Sep 17 00:00:00 2001
From: Blacktempel <6657796+Blacktempel@users.noreply.github.com>
Date: Tue, 23 Sep 2025 10:38:48 +0200
Subject: [PATCH] Fix memory only being available for Intel (#1887)
* Current implementation of PawnIo.LoadModuleFromResource swallows exceptions instead of throwing them like it has been previously.
It also returns a not-null PawnIo object.
RAMSPDToolkitDriver has been catching exception, returning false for LoadModule and checking if returned object is null.
Therefore the return for a failed loaded module was true where it should have been false.
Returning null from PawnIo.LoadModuleFromResource in catch block fixes this issue.
* Add IsValid property for PawnIo and check in RAMSPDToolkitDriver.
Remove null return.
* Update RAMSPDToolkit to newest version.
Fixes bug in .NET Framework and changed PawnIO interface due to adjusted Piix4 detection.
Add new Data sensor.
* Rename property.
---
.../Hardware/Memory/DimmMemory.cs | 5 ++
.../LibreHardwareMonitorLib.csproj | 2 +-
LibreHardwareMonitorLib/PawnIo/PawnIo.cs | 2 +
.../RAMSPDToolkitDriver.cs | 63 ++++++++++++++-----
4 files changed, 57 insertions(+), 15 deletions(-)
diff --git a/LibreHardwareMonitorLib/Hardware/Memory/DimmMemory.cs b/LibreHardwareMonitorLib/Hardware/Memory/DimmMemory.cs
index 0ec4de8..42126bd 100644
--- a/LibreHardwareMonitorLib/Hardware/Memory/DimmMemory.cs
+++ b/LibreHardwareMonitorLib/Hardware/Memory/DimmMemory.cs
@@ -96,6 +96,8 @@ internal sealed class DimmMemory : Hardware
AddSensor("tWTR_S (Write to Read Time)", 16, false, SensorType.Timing, (float)accessor.SDRAMTimings.MinimumWriteToReadTime_DiffGroup);
AddSensor("tWTR_L (Write to Read Time)", 17, false, SensorType.Timing, (float)accessor.SDRAMTimings.MinimumWriteToReadTime_SameGroup);
+ //Data
+ AddSensor("Capacity", 18, false, SensorType.Data, accessor.GetCapacity());
}
private void CreateSensorsDDR5(DDR5Accessor accessor, bool hasThermalSensor)
@@ -121,6 +123,9 @@ internal sealed class DimmMemory : Hardware
AddSensor("tRFC1_dlr (Normal Refresh Recovery Time 3DS)", 12, false, SensorType.Timing, (float)accessor.SDRAMTimings.NormalRefreshRecoveryTime_3DSDifferentLogicalRank);
AddSensor("tRFC2_dlr (Fine Granularity Refresh Recovery Time 3DS)", 13, false, SensorType.Timing, (float)accessor.SDRAMTimings.FineGranularityRefreshRecoveryTime_3DSDifferentLogicalRank);
AddSensor("tRFCsb_dlr (Same Bank Refresh Recovery Time 3DS)", 14, false, SensorType.Timing, (float)accessor.SDRAMTimings.SameBankRefreshRecoveryTime_3DSDifferentLogicalRank);
+
+ //Data
+ AddSensor("Capacity", 15, false, SensorType.Data, accessor.GetCapacity());
}
private void AddSensor(string name, int index, bool defaultHidden, SensorType sensorType, float value)
diff --git a/LibreHardwareMonitorLib/LibreHardwareMonitorLib.csproj b/LibreHardwareMonitorLib/LibreHardwareMonitorLib.csproj
index 3bc5419..bae2704 100644
--- a/LibreHardwareMonitorLib/LibreHardwareMonitorLib.csproj
+++ b/LibreHardwareMonitorLib/LibreHardwareMonitorLib.csproj
@@ -48,7 +48,7 @@
-
+
diff --git a/LibreHardwareMonitorLib/PawnIo/PawnIo.cs b/LibreHardwareMonitorLib/PawnIo/PawnIo.cs
index 57cc3ed..d8f0d3b 100644
--- a/LibreHardwareMonitorLib/PawnIo/PawnIo.cs
+++ b/LibreHardwareMonitorLib/PawnIo/PawnIo.cs
@@ -41,6 +41,8 @@ public unsafe class PawnIo
get { return !string.IsNullOrEmpty(InstallPath); }
}
+ public bool IsLoaded => _handle != IntPtr.Zero;
+
[DllImport("PawnIOLib", ExactSpelling = true, PreserveSig = false)]
private static extern void pawnio_version(out uint version);
diff --git a/LibreHardwareMonitorLib/RAMSPDToolkitDriver.cs b/LibreHardwareMonitorLib/RAMSPDToolkitDriver.cs
index 8ebee50..8d5153b 100644
--- a/LibreHardwareMonitorLib/RAMSPDToolkitDriver.cs
+++ b/LibreHardwareMonitorLib/RAMSPDToolkitDriver.cs
@@ -1,30 +1,49 @@
-using RAMSPDToolkit.I2CSMBus.Interop.PawnIO;
+using System;
+using System.Collections.Generic;
+using RAMSPDToolkit.I2CSMBus.Interop.PawnIO;
using RAMSPDToolkit.Windows.Driver.Interfaces;
namespace LibreHardwareMonitor;
-internal class RAMSPDToolkitDriver : IPawnIODriver
+internal sealed class RAMSPDToolkitDriver : IPawnIODriver
{
+ internal class PawnIOModule : IPawnIOModule, IDisposable
+ {
+ public PawnIOModule(PawnIo.PawnIo pawnIO)
+ {
+ _pawnIO = pawnIO;
+ }
+
+ PawnIo.PawnIo _pawnIO;
+
+ public int Execute(string name, long[] inBuffer, uint inSize, long[] outBuffer, uint outSize, out uint returnSize)
+ => _pawnIO.ExecuteHr(name, inBuffer, inSize, outBuffer, outSize, out returnSize);
+
+ public void Dispose()
+ {
+ if (_pawnIO != null)
+ {
+ _pawnIO.Close();
+ _pawnIO = null;
+ }
+ }
+ }
+
const string I801ModuleFilename = "SmbusI801.bin";
const string Piix4ModuleFilename = "SmbusPIIX4.bin";
const string Nct6793ModuleFilename = "SmbusNCT6793.bin";
- private PawnIo.PawnIo _pawnIO;
+ private List _pawnIOModules = new();
public bool IsOpen => true;
- public int Execute(string name, long[] inBuffer, uint inSize, long[] outBuffer, uint outSize, out uint returnSize)
- {
- return _pawnIO.ExecuteHr(name, inBuffer, inSize, outBuffer, outSize, out returnSize);
- }
-
public bool Load()
{
//Not required
return true;
}
- public bool LoadModule(PawnIOSMBusIdentifier pawnIOSMBusIdentifier)
+ public IPawnIOModule LoadModule(PawnIOSMBusIdentifier pawnIOSMBusIdentifier)
{
string moduleResourceFilename = pawnIOSMBusIdentifier switch
{
@@ -36,23 +55,39 @@ internal class RAMSPDToolkitDriver : IPawnIODriver
if (moduleResourceFilename == null)
{
- return false;
+ return null;
}
+ PawnIOModule pawnIOModule = null;
+
try
{
- _pawnIO = PawnIo.PawnIo.LoadModuleFromResource(typeof(RAMSPDToolkitDriver).Assembly, $"{nameof(LibreHardwareMonitor)}.Resources.PawnIO.{moduleResourceFilename}");
+ var pawnIO = PawnIo.PawnIo.LoadModuleFromResource(typeof(RAMSPDToolkitDriver).Assembly, $"{nameof(LibreHardwareMonitor)}.Resources.PawnIO.{moduleResourceFilename}");
+
+ if (pawnIO.IsLoaded)
+ {
+ pawnIOModule = new PawnIOModule(pawnIO);
+ }
}
catch
{
- return false;
+ return null;
}
- return _pawnIO != null;
+ if (pawnIOModule != null)
+ {
+ _pawnIOModules.Add(pawnIOModule);
+ return pawnIOModule;
+ }
+ else
+ {
+ return null;
+ }
}
public void Unload()
{
- _pawnIO.Close();
+ _pawnIOModules.ForEach(p => p.Dispose());
+ _pawnIOModules.Clear();
}
}