Fix ASUS Z170 EC temperature read returning zero values (#2153)

* Fix ASUS Z170 EC temperature read returning zero values
Adjust EC read logic so temperature registers (PCH, T_SENSOR, VRM)
return valid values on ASUS Z170 boards in user-mode.
Verified with RWEverything and HWiNFO.

* merge back to inter100,
Use IBF clearing fallback when OBF unsupported

* Fix formatting of CrOS enum entry

* Update WindowsEmbeddedControllerIO.cs

---------

Co-authored-by: PhyxionNL <7643972+PhyxionNL@users.noreply.github.com>
This commit is contained in:
Wiktor
2026-02-01 15:40:16 +01:00
committed by GitHub
co-authored by PhyxionNL
parent 883f24d149
commit 2423b1b7f1
4 changed files with 81 additions and 56 deletions
@@ -391,6 +391,8 @@ internal class Identification
return Model.ROG_ZENITH_II_EXTREME;
case var _ when name.Equals("Z170-A", StringComparison.OrdinalIgnoreCase):
return Model.Z170_A;
case var _ when name.Equals("Z170 PRO GAMING", StringComparison.OrdinalIgnoreCase):
return Model.Z170_PRO_GAMING;
case var _ when name.Equals("B150M-C", StringComparison.OrdinalIgnoreCase):
return Model.B150M_C;
case var _ when name.Equals("B150M-C D3", StringComparison.OrdinalIgnoreCase):
@@ -257,6 +257,11 @@ public abstract class EmbeddedController : Hardware
ECSensor.FanWaterPump,
ECSensor.CurrCPU,
ECSensor.VoltageCPU),
new(Model.Z170_PRO_GAMING,
BoardFamily.Intel100,
ECSensor.TempChipset,
ECSensor.TempVrm,
ECSensor.TempTSensor),
new(Model.PRIME_Z690_A,
BoardFamily.Intel600,
ECSensor.TempTSensor,
@@ -398,6 +403,7 @@ public abstract class EmbeddedController : Hardware
BoardFamily.Intel100, new Dictionary<ECSensor, EmbeddedControllerSource>
{
{ ECSensor.TempChipset, new EmbeddedControllerSource("Chipset", SensorType.Temperature, 0x003a) },
{ ECSensor.TempVrm, new EmbeddedControllerSource("VRM", SensorType.Temperature, 0x003e) },
{ ECSensor.TempTSensor, new EmbeddedControllerSource("T Sensor", SensorType.Temperature, 0x003d, blank: -40) },
{ ECSensor.FanWaterPump, new EmbeddedControllerSource("Water Pump", SensorType.Fan, 0x00bc, 2) },
{ ECSensor.CurrCPU, new EmbeddedControllerSource("CPU", SensorType.Current, 0x00f4) },
@@ -3,7 +3,6 @@
// Copyright (C) LibreHardwareMonitor and Contributors.
// All Rights Reserved.
using System;
using System.Diagnostics;
using System.Threading;
using LibreHardwareMonitor.PawnIo;
@@ -25,12 +24,12 @@ public class WindowsEmbeddedControllerIO : IEmbeddedControllerIO
// implementation
private const int WaitSpins = 50;
private readonly LpcAcpiEc _pawnModule;
private bool _disposed;
private int _waitReadFailures;
private readonly LpcAcpiEc _pawnModule;
public WindowsEmbeddedControllerIO()
{
_pawnModule = new LpcAcpiEc();
@@ -62,22 +61,13 @@ public class WindowsEmbeddedControllerIO : IEmbeddedControllerIO
{
bank = SwitchBank(regBank);
}
data[i] = ReadByte(regIndex);
}
SwitchBank(prevBank);
}
private byte ReadByte(byte register)
{
return ReadLoop<byte>(register, ReadByteOp);
}
private void WriteByte(byte register, byte value)
{
WriteLoop(register, value, WriteByteOp);
}
public void Dispose()
{
if (!_disposed)
@@ -88,6 +78,16 @@ public class WindowsEmbeddedControllerIO : IEmbeddedControllerIO
}
}
private byte ReadByte(byte register)
{
return ReadLoop<byte>(register, ReadByteOp);
}
private void WriteByte(byte register, byte value)
{
WriteLoop(register, value, WriteByteOp);
}
private byte SwitchBank(byte bank)
{
byte previous = ReadByte(0xFF);
@@ -145,10 +145,31 @@ public class WindowsEmbeddedControllerIO : IEmbeddedControllerIO
return true;
}
if (WaitForStatus(Status.OutputBufferFull, true))
// Try OBF with reduced timeout
for (int i = 0; i < MaxRetries; i++)
{
_waitReadFailures = 0;
return true;
byte status = ReadIOPort(Port.Command);
if ((status & (byte)Status.OutputBufferFull) != 0)
{
_waitReadFailures = 0;
return true;
}
Thread.Sleep(1);
}
// ASUS workaround: Wait for IBF to clear instead of OBF
// Testing on Z170 Pro Gaming shows IBF clears in 1-3ms when data is ready
for (int i = 0; i < WaitSpins; i++)
{
byte status = ReadIOPort(Port.Command);
if ((status & (byte)Status.InputBufferFull) == 0)
{
_waitReadFailures = 0;
return true;
}
Thread.Sleep(1);
}
_waitReadFailures++;
@@ -170,45 +191,6 @@ public class WindowsEmbeddedControllerIO : IEmbeddedControllerIO
_pawnModule.WritePort((byte)port, datum);
}
public class BusMutexLockingFailedException : EmbeddedController.IOException
{
public BusMutexLockingFailedException()
: base("could not lock ISA bus mutex")
{ }
}
private delegate bool ReadOp<TParam>(byte register, out TParam p);
private delegate bool WriteOp<in TParam>(byte register, TParam p);
// see the ACPI specification chapter 12
private enum Port : byte
{
Command = 0x66,
Data = 0x62
}
private enum Command : byte
{
Read = 0x80, // RD_EC
Write = 0x81, // WR_EC
BurstEnable = 0x82, // BE_EC
BurstDisable = 0x83, // BD_EC
Query = 0x84 // QR_EC
}
private enum Status : byte
{
OutputBufferFull = 0x01, // EC_OBF
InputBufferFull = 0x02, // EC_IBF
Command = 0x08, // CMD
BurstMode = 0x10, // BURST
SciEventPending = 0x20, // SCI_EVT
SmiEventPending = 0x40 // SMI_EVT
}
#region Read/Write ops
protected bool ReadByteOp(byte register, out byte value)
{
if (WaitWrite())
@@ -250,5 +232,39 @@ public class WindowsEmbeddedControllerIO : IEmbeddedControllerIO
return false;
}
#endregion
public class BusMutexLockingFailedException : EmbeddedController.IOException
{
public BusMutexLockingFailedException() : base("could not lock ISA bus mutex")
{ }
}
private delegate bool ReadOp<TParam>(byte register, out TParam p);
private delegate bool WriteOp<in TParam>(byte register, TParam p);
// see the ACPI specification chapter 12
private enum Port : byte
{
Command = 0x66,
Data = 0x62
}
private enum Command : byte
{
Read = 0x80, // RD_EC
Write = 0x81, // WR_EC
BurstEnable = 0x82, // BE_EC
BurstDisable = 0x83, // BD_EC
Query = 0x84 // QR_EC
}
private enum Status : byte
{
OutputBufferFull = 0x01, // EC_OBF
InputBufferFull = 0x02, // EC_IBF
Command = 0x08, // CMD
BurstMode = 0x10, // BURST
SciEventPending = 0x20, // SCI_EVT
SmiEventPending = 0x40 // SMI_EVT
}
}
@@ -115,6 +115,7 @@ public enum Model
TUF_X470_PLUS_GAMING,
TUF_GAMING_X870_PLUS_WIFI,
Z170_A,
Z170_PRO_GAMING,
B150M_C,
B150M_C_D3,
TUF_GAMING_X570_PLUS_WIFI,