* Try and migrate the old GigabyteController stuff with PawnIO * Bring back WinRing0 era GigabyteController stuff * ISABridge use the PawnIO module with its built-in logic * Ecio uses LpcIO directly (not sure about the initialization logic in TryCreate() to make this work) * Code-review * Fix inverted logic * Remove IsaBridgeEc field init * Format document * Combine logic * Gigabyte Implementation best attempt * Update IsaBridgeGigabyteController.cs * Cleanup and fix enablind logic for Isa version * Add debug logs * Update IsaBridgeGigabyteController.cs * Code review * Unmap + restore the mmio state is done through the closing of the module. * Fix boolean logic * Restore the fan control byte instead * Fallback to ECIO if FanControl enable byte is 0xFF + add logs to ECIO * Port back to validation logic * Allow for one or the other MMIO to be 0 * Wrap enter/exit mmio logic + enter/exit each time * Keep state of EcioPort enable * Missing dispose + close order fix * Update IsaBridgeGigabyteController.cs * Remove empty line before TryCreate method * Code review * Remove try/finally for SW * Cleanup debug log methods * Add DEBUG_LOG define conditional * Misc * Misc --------- Co-authored-by: PhyxionNL <7643972+PhyxionNL@users.noreply.github.com>
191 lines
6.2 KiB
C#
191 lines
6.2 KiB
C#
//#define ISA_BRIDGE_EC_DEBUG
|
|
|
|
using System.Diagnostics;
|
|
|
|
namespace LibreHardwareMonitor.PawnIo
|
|
{
|
|
public enum MMIOState
|
|
{
|
|
Unknown = -999,
|
|
|
|
MMIO_Original = -1,
|
|
MMIO_Disabled = 0,
|
|
MMIO_Enabled2E = 1,
|
|
MMIO_Enabled4E = 2,
|
|
MMIO_EnabledBoth = 3
|
|
};
|
|
|
|
public struct MMIOMapping
|
|
{
|
|
public int Index;
|
|
public long BaseAddress;
|
|
public long SuperIoSize;
|
|
public long ChipId;
|
|
}
|
|
|
|
public class IsaBridgeEc
|
|
{
|
|
private readonly PawnIo _pawnIO = PawnIo.LoadModuleFromResource(typeof(IsaBridgeEc).Assembly, $"{nameof(LibreHardwareMonitor)}.Resources.PawnIo.IsaBridgeEC.bin");
|
|
|
|
// ioctl_find_superio_mmio
|
|
public bool FindSuperIoMMIO(out MMIOMapping firstMmio, out MMIOMapping secondMmio)
|
|
{
|
|
long[] outArray = new long[6];
|
|
int ntStatusCode = _pawnIO.ExecuteHr("ioctl_find_superio_mmio", [], 0, outArray, 6, out uint returnSize);
|
|
|
|
Log($"FindSuperIoMMIO statusCode: {ntStatusCode}");
|
|
|
|
if (ntStatusCode != 0)
|
|
{
|
|
firstMmio = default;
|
|
secondMmio = default;
|
|
return false;
|
|
}
|
|
|
|
firstMmio = new MMIOMapping
|
|
{
|
|
Index = 0,
|
|
BaseAddress = outArray[0],
|
|
SuperIoSize = outArray[1],
|
|
ChipId = outArray[2]
|
|
};
|
|
|
|
secondMmio = new MMIOMapping
|
|
{
|
|
Index = 1,
|
|
BaseAddress = outArray[3],
|
|
SuperIoSize = outArray[4],
|
|
ChipId = outArray[5]
|
|
};
|
|
|
|
Log($"First MMIO - BaseAddress: 0x{firstMmio.BaseAddress:X}, SuperIoSize: 0x{firstMmio.SuperIoSize:X}, ChipId: 0x{firstMmio.ChipId:X}");
|
|
Log($"Second MMIO - BaseAddress: 0x{secondMmio.BaseAddress:X}, SuperIoSize: 0x{secondMmio.SuperIoSize:X}, ChipId: 0x{secondMmio.ChipId:X}");
|
|
|
|
return firstMmio.BaseAddress != 0 || secondMmio.BaseAddress != 0;
|
|
}
|
|
|
|
//ioctl_access_superio_mmio
|
|
public bool ReadMmio(long superIoIndex, long offset, long size, out byte value)
|
|
{
|
|
long[] inArray = new long[5] {
|
|
superIoIndex, // superio index
|
|
offset, // offset
|
|
size, // size
|
|
0, // is write?
|
|
0 // value (ignored for read)
|
|
};
|
|
|
|
long[] outarray = new long[1];
|
|
|
|
int ntStatusCode = _pawnIO.ExecuteHr("ioctl_access_superio_mmio", inArray, 5, outarray, 1, out uint returnSize);
|
|
|
|
Log($"ReadMmio statusCode: {ntStatusCode}, Read Value: 0x{outarray[0]:X} at SuperIoIndex {superIoIndex}, offset {offset}, size {size}");
|
|
|
|
value = (byte)outarray[0];
|
|
|
|
return ntStatusCode == 0;
|
|
}
|
|
|
|
//ioctl_access_superio_mmio
|
|
public bool WriteMmio(long superIoIndex, long offset, long size, byte value)
|
|
{
|
|
long[] inArray = new long[5] {
|
|
superIoIndex, // superio index
|
|
offset, // offset
|
|
size, // size
|
|
1, // is write?
|
|
value // value
|
|
};
|
|
|
|
long[] outarray = new long[1];
|
|
|
|
int ntStatusCode = _pawnIO.ExecuteHr("ioctl_access_superio_mmio", inArray, 5, outarray, 1, out uint returnSize);
|
|
|
|
Log($"WriteMmio statusCode: {ntStatusCode}, Written Value: 0x{value:X} at SuperIoIndex {superIoIndex}, offset {offset}, size {size}");
|
|
|
|
return ntStatusCode == 0;
|
|
}
|
|
|
|
// ioctl_map_superio_mmio
|
|
public bool Map()
|
|
{
|
|
int ntStatusCode = _pawnIO.ExecuteHr("ioctl_map_superio_mmio", [], 0, [], 0, out uint returnSize);
|
|
|
|
Log($"Map statusCode: {ntStatusCode}");
|
|
|
|
return ntStatusCode == 0;
|
|
}
|
|
|
|
// ioctl_unmap_superio_mmio
|
|
public bool Unmap()
|
|
{
|
|
int ntStatusCode = _pawnIO.ExecuteHr("ioctl_unmap_superio_mmio", [], 0, [], 0, out uint returnSize);
|
|
|
|
Log($"Unmap statusCode: {ntStatusCode}");
|
|
|
|
return ntStatusCode == 0;
|
|
}
|
|
|
|
// ioctl_access_superio_mmio
|
|
public bool GetOriginalState(out MMIOState state)
|
|
{
|
|
state = MMIOState.Unknown;
|
|
long[] outArray = new long[1];
|
|
int ntStatusCode = _pawnIO.ExecuteHr("ioctl_iomem_mmio_get_org_state", [], 0, outArray, 1, out uint returnSize);
|
|
|
|
Log($"GetOriginalState statusCode: {ntStatusCode}");
|
|
|
|
|
|
if (ntStatusCode != 0)
|
|
return false;
|
|
|
|
Log($"Original MMIO State: {(MMIOState)outArray[0]}");
|
|
|
|
state = (MMIOState)outArray[0];
|
|
return true;
|
|
}
|
|
|
|
public bool TryGetCurrentState(out MMIOState state)
|
|
{
|
|
state = MMIOState.Unknown;
|
|
long[] outArray = new long[1];
|
|
int ntStatusCode = _pawnIO.ExecuteHr("ioctl_iomem_mmio_get_cur_state", [], 0, outArray, 1, out uint returnSize);
|
|
|
|
if (ntStatusCode != 0)
|
|
return false;
|
|
|
|
state = (MMIOState)outArray[0];
|
|
return true;
|
|
}
|
|
|
|
public bool TrySetState(MMIOState state)
|
|
{
|
|
long[] inArray = new long[1];
|
|
inArray[0] = (long)state;
|
|
int ntStatusCode = _pawnIO.ExecuteHr("ioctl_iomem_mmio_set_state", inArray, 1, [], 0, out uint returnSize);
|
|
|
|
Log($"TrySetState to {state} statusCode: {ntStatusCode}");
|
|
|
|
if (ntStatusCode != 0)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
public void Close() => _pawnIO.Close();
|
|
|
|
/// <summary>
|
|
/// Writes a debug message to both the output window and a log file when ISA_BRIDGE_EC_DEBUG is defined.
|
|
/// </summary>
|
|
/// <remarks>The log entry is timestamped and appended to the file
|
|
/// 'PawnIo_IsaBridgeEc_DebugLog.txt' in the application's working directory. This method only produces output
|
|
/// when compiled with the ISA_BRIDGE_EC_DEBUG symbol defined.</remarks>
|
|
/// <param name="message">The message to log. This should provide relevant information for debugging purposes.</param>
|
|
[Conditional("DEBUG_LOG"), Conditional("ISA_BRIDGE_EC_DEBUG")]
|
|
private static void Log(string message)
|
|
{
|
|
Debug.WriteLine(message);
|
|
}
|
|
}
|
|
}
|