diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Identification.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Identification.cs index 56833f7..d8b480e 100644 --- a/LibreHardwareMonitorLib/Hardware/Motherboard/Identification.cs +++ b/LibreHardwareMonitorLib/Hardware/Motherboard/Identification.cs @@ -301,6 +301,8 @@ namespace LibreHardwareMonitor.Hardware.Motherboard return Model.AX370_Gaming_K7; case var _ when name.Equals("PRIME X370-PRO", StringComparison.OrdinalIgnoreCase): return Model.PRIME_X370_PRO; + case var _ when name.Equals("PRIME X470-PRO", StringComparison.OrdinalIgnoreCase): + return Model.PRIME_X470_PRO; case var _ when name.Equals("PRIME X570-PRO", StringComparison.OrdinalIgnoreCase): return Model.PRIME_X570_PRO; case var _ when name.Equals("Pro WS X570-ACE", StringComparison.OrdinalIgnoreCase): diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/EC/EmbeddedController.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/EC/EmbeddedController.cs index b3a069e..939f7cd 100644 --- a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/EC/EmbeddedController.cs +++ b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/EC/EmbeddedController.cs @@ -25,6 +25,8 @@ namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc.EC TempTSensor, /// VRM temperature [℃] TempVrm, + /// CPU Core voltage [mV] + VoltageCPU, /// CPU_Opt fan [RPM] FanCPUOpt, /// VRM heat sink fan [RPM] @@ -44,110 +46,160 @@ namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc.EC Max }; - private static readonly Dictionary _knownSensors = new() + private enum BoardFamily { - { ECSensor.TempChipset, new EmbeddedControllerSource("Chipset", SensorType.Temperature, 0x003a) }, - { ECSensor.TempCPU, new EmbeddedControllerSource("CPU", SensorType.Temperature, 0x003b) }, - { ECSensor.TempMB, new EmbeddedControllerSource("Motherboard", SensorType.Temperature, 0x003c) }, - { ECSensor.TempTSensor, new EmbeddedControllerSource("T Sensor", SensorType.Temperature, 0x003d, blank: -40) }, - { ECSensor.TempVrm, new EmbeddedControllerSource("VRM", SensorType.Temperature, 0x003e) }, - { ECSensor.FanCPUOpt, new EmbeddedControllerSource("CPU Optional Fan", SensorType.Fan, 0x00b0, 2) }, - { ECSensor.FanVrmHS, new EmbeddedControllerSource("VRM Heat Sink Fan", SensorType.Fan, 0x00b2, 2) }, - { ECSensor.FanChipset, new EmbeddedControllerSource("Chipset Fan", SensorType.Fan, 0x00b4, 2) }, - { ECSensor.FanWaterPump, new EmbeddedControllerSource("Water Pump", SensorType.Fan, 0x00bc, 2) }, - // TODO: "why 42?" is a silly question, I know, but still, why? On the serious side, it might be 41.6(6) - { ECSensor.FanWaterFlow, new EmbeddedControllerSource("Water flow", SensorType.Flow, 0x00bc, 2, factor: 1.0f / 42f * 60f) }, - { ECSensor.CurrCPU, new EmbeddedControllerSource("CPU", SensorType.Current, 0x00f4) }, - { ECSensor.TempWaterIn, new EmbeddedControllerSource("Water In", SensorType.Temperature, 0x0100, blank: -40) }, - { ECSensor.TempWaterOut, new EmbeddedControllerSource("Water Out", SensorType.Temperature, 0x0101, blank: -40) }, + Amd400, + Amd500, + Intel100, + Intel600, + } + + private struct BoardInfo + { + public BoardInfo(Model[] models, BoardFamily family, params ECSensor[] sensors) + { + Models = models; + Family = family; + Sensors = sensors; + } + + public BoardInfo(Model model, BoardFamily family, params ECSensor[] sensors) + { + Models = new Model[] { model }; + Family = family; + Sensors = sensors; + } + + public Model[] Models { get; } + public BoardFamily Family { get; } + public ECSensor[] Sensors { get; } }; - private static readonly Dictionary _boardSensors = new() + private static readonly Dictionary> _knownSensors = new() { { - Model.PRIME_X570_PRO, - new ECSensor[] { ECSensor.TempChipset, ECSensor.TempCPU, ECSensor.TempMB, - ECSensor.TempVrm, ECSensor.TempTSensor, ECSensor.FanChipset } - }, - { - Model.PRO_WS_X570_ACE, - new ECSensor[] { ECSensor.TempChipset, ECSensor.TempCPU, ECSensor.TempMB , - ECSensor.TempVrm, ECSensor.FanChipset, ECSensor.CurrCPU} - }, - { - Model.ROG_CROSSHAIR_VIII_HERO, - new ECSensor[] { ECSensor.TempChipset, ECSensor.TempCPU, ECSensor.TempMB, - ECSensor.TempTSensor, ECSensor.TempVrm, ECSensor.TempWaterIn, ECSensor.TempWaterOut, - ECSensor.FanCPUOpt, ECSensor.FanChipset, ECSensor.FanWaterFlow, ECSensor.CurrCPU} - }, - { - Model.ROG_CROSSHAIR_VIII_HERO_WIFI, - new ECSensor[] { ECSensor.TempChipset, ECSensor.TempCPU, ECSensor.TempMB, - ECSensor.TempTSensor, ECSensor.TempVrm, ECSensor.TempWaterIn, ECSensor.TempWaterOut, - ECSensor.FanCPUOpt, ECSensor.FanChipset, ECSensor.FanWaterFlow, ECSensor.CurrCPU} - }, - { - Model.ROG_CROSSHAIR_VIII_DARK_HERO, - new ECSensor[] { ECSensor.TempChipset, ECSensor.TempCPU, ECSensor.TempMB, - ECSensor.TempTSensor, ECSensor.TempVrm, ECSensor.TempWaterIn, ECSensor.TempWaterOut, - ECSensor.FanCPUOpt, ECSensor.FanWaterFlow, ECSensor.CurrCPU + BoardFamily.Amd400, + new() // no chipset fans in this generation + { + { ECSensor.TempChipset, new EmbeddedControllerSource("Chipset", SensorType.Temperature, 0x003a) }, + { ECSensor.TempCPU, new EmbeddedControllerSource("CPU", SensorType.Temperature, 0x003b) }, + { ECSensor.TempMB, new EmbeddedControllerSource("Motherboard", SensorType.Temperature, 0x003c) }, + { ECSensor.TempTSensor, new EmbeddedControllerSource("T Sensor", SensorType.Temperature, 0x003d, blank: -40) }, + { ECSensor.TempVrm, new EmbeddedControllerSource("VRM", SensorType.Temperature, 0x003e) }, + { ECSensor.VoltageCPU, new EmbeddedControllerSource("CPU Core", SensorType.Voltage, 0x00a2, 2, factor: 1e-3f) }, + { ECSensor.FanCPUOpt, new EmbeddedControllerSource("CPU Optional Fan", SensorType.Fan, 0x00bc, 2) }, + { ECSensor.FanVrmHS, new EmbeddedControllerSource("VRM Heat Sink Fan", SensorType.Fan, 0x00b2, 2) }, + { ECSensor.FanWaterFlow, new EmbeddedControllerSource("Water flow", SensorType.Flow, 0x00b4, 2, factor: 1.0f / 42f * 60f) }, + { ECSensor.CurrCPU, new EmbeddedControllerSource("CPU", SensorType.Current, 0x00f4) }, + { ECSensor.TempWaterIn, new EmbeddedControllerSource("Water In", SensorType.Temperature, 0x010d, blank: -40) }, + { ECSensor.TempWaterOut, new EmbeddedControllerSource("Water Out", SensorType.Temperature, 0x010b, blank: -40) }, } }, { - Model.CROSSHAIR_III_FORMULA, - new ECSensor[] { ECSensor.TempChipset, ECSensor.TempCPU, ECSensor.TempMB, - ECSensor.TempTSensor, ECSensor.TempVrm, - ECSensor.FanCPUOpt, ECSensor.FanChipset, ECSensor.CurrCPU } + BoardFamily.Amd500, + new() + { + { ECSensor.TempChipset, new EmbeddedControllerSource("Chipset", SensorType.Temperature, 0x003a) }, + { ECSensor.TempCPU, new EmbeddedControllerSource("CPU", SensorType.Temperature, 0x003b) }, + { ECSensor.TempMB, new EmbeddedControllerSource("Motherboard", SensorType.Temperature, 0x003c) }, + { ECSensor.TempTSensor, new EmbeddedControllerSource("T Sensor", SensorType.Temperature, 0x003d, blank: -40) }, + { ECSensor.TempVrm, new EmbeddedControllerSource("VRM", SensorType.Temperature, 0x003e) }, + { ECSensor.VoltageCPU, new EmbeddedControllerSource("CPU Core", SensorType.Voltage, 0x00a2, 2, factor: 1e-3f) }, + { ECSensor.FanCPUOpt, new EmbeddedControllerSource("CPU Optional Fan", SensorType.Fan, 0x00b0, 2) }, + { ECSensor.FanVrmHS, new EmbeddedControllerSource("VRM Heat Sink Fan", SensorType.Fan, 0x00b2, 2) }, + { ECSensor.FanChipset, new EmbeddedControllerSource("Chipset Fan", SensorType.Fan, 0x00b4, 2) }, + // TODO: "why 42?" is a silly question, I know, but still, why? On the serious side, it might be 41.6(6) + { ECSensor.FanWaterFlow, new EmbeddedControllerSource("Water flow", SensorType.Flow, 0x00bc, 2, factor: 1.0f / 42f * 60f) }, + { ECSensor.CurrCPU, new EmbeddedControllerSource("CPU", SensorType.Current, 0x00f4) }, + { ECSensor.TempWaterIn, new EmbeddedControllerSource("Water In", SensorType.Temperature, 0x0100, blank: -40) }, + { ECSensor.TempWaterOut, new EmbeddedControllerSource("Water Out", SensorType.Temperature, 0x0101, blank: -40) }, + } }, { - Model.ROG_CROSSHAIR_VIII_IMPACT, - new ECSensor[] { ECSensor.TempChipset, ECSensor.TempCPU, ECSensor.TempMB, - ECSensor.TempTSensor, ECSensor.TempVrm, - ECSensor.FanChipset, ECSensor.CurrCPU } + BoardFamily.Intel100, + new() { + { ECSensor.TempChipset, new EmbeddedControllerSource("Chipset", SensorType.Temperature, 0x003a) }, + { 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) }, + { ECSensor.VoltageCPU, new EmbeddedControllerSource("CPU Core", SensorType.Voltage, 0x00a2, 2, factor: 1e-3f) }, + } }, { - Model.ROG_STRIX_B550_E_GAMING, - new ECSensor[] { ECSensor.TempChipset, ECSensor.TempCPU, ECSensor.TempMB, - ECSensor.TempTSensor, ECSensor.TempVrm, ECSensor.FanCPUOpt } + BoardFamily.Intel600, + new() + { + { ECSensor.TempTSensor, new EmbeddedControllerSource("T Sensor", SensorType.Temperature, 0x003d, blank: -40) }, + { ECSensor.TempVrm, new EmbeddedControllerSource("VRM", SensorType.Temperature, 0x003e) }, + } }, - { - Model.ROG_STRIX_B550_I_GAMING, - new ECSensor[] { ECSensor.TempChipset, ECSensor.TempCPU, ECSensor.TempMB, - ECSensor.TempTSensor, ECSensor.TempVrm, - ECSensor.FanVrmHS, ECSensor.CurrCPU } - }, - { - Model.ROG_STRIX_X570_E_GAMING, - new ECSensor[] { ECSensor.TempChipset, ECSensor.TempCPU, ECSensor.TempMB, - ECSensor.TempTSensor, ECSensor.TempVrm, - ECSensor.FanChipset, ECSensor.CurrCPU } - }, - { - Model.ROG_STRIX_X570_F_GAMING, - new ECSensor[]{ECSensor.TempChipset, ECSensor.TempCPU, ECSensor.TempMB, - ECSensor.TempTSensor, ECSensor.FanChipset} - }, - { - Model.ROG_STRIX_X570_I_GAMING, - new ECSensor[] { - ECSensor.TempTSensor, ECSensor.FanVrmHS, ECSensor.FanChipset, ECSensor.CurrCPU } - }, - { - Model.ROG_STRIX_Z690_A_GAMING_WIFI_D4, - new ECSensor[] { - ECSensor.TempTSensor, ECSensor.TempVrm } - }, - { - Model.Z170_A, - new ECSensor[] { - ECSensor.TempTSensor, ECSensor.TempChipset, ECSensor.FanWaterPump, ECSensor.CurrCPU } - } }; - static EmbeddedController() - { - System.Diagnostics.Debug.Assert(_knownSensors.Count == ((int)ECSensor.Max)); - } + private static readonly BoardInfo[] _boards = new BoardInfo[]{ + new(Model.PRIME_X470_PRO, BoardFamily.Amd400, + ECSensor.TempChipset, ECSensor.TempCPU, ECSensor.TempMB, + ECSensor.TempVrm, ECSensor.TempVrm, ECSensor.FanCPUOpt, + ECSensor.CurrCPU, ECSensor.VoltageCPU + ), + new (Model.PRIME_X570_PRO, BoardFamily.Amd500, + ECSensor.TempChipset, ECSensor.TempCPU, ECSensor.TempMB, + ECSensor.TempVrm, ECSensor.TempTSensor, ECSensor.FanChipset + ), + new(Model.PRO_WS_X570_ACE, BoardFamily.Amd500, + ECSensor.TempChipset, ECSensor.TempCPU, ECSensor.TempMB, + ECSensor.TempVrm, ECSensor.FanChipset, ECSensor.CurrCPU, ECSensor.VoltageCPU + ), + new(new Model[] {Model.ROG_CROSSHAIR_VIII_HERO, Model.ROG_CROSSHAIR_VIII_HERO_WIFI }, BoardFamily.Amd500, + ECSensor.TempChipset, ECSensor.TempCPU, ECSensor.TempMB, + ECSensor.TempTSensor, ECSensor.TempVrm, ECSensor.TempWaterIn, ECSensor.TempWaterOut, + ECSensor.FanCPUOpt, ECSensor.FanChipset, ECSensor.FanWaterFlow, + ECSensor.CurrCPU, ECSensor.VoltageCPU + ), + new(Model.ROG_CROSSHAIR_VIII_DARK_HERO, BoardFamily.Amd500, + ECSensor.TempChipset, ECSensor.TempCPU, ECSensor.TempMB, + ECSensor.TempTSensor, ECSensor.TempVrm, ECSensor.TempWaterIn, ECSensor.TempWaterOut, + ECSensor.FanCPUOpt, ECSensor.FanWaterFlow, ECSensor.CurrCPU, ECSensor.VoltageCPU + ), + new(Model.CROSSHAIR_III_FORMULA, BoardFamily.Amd500, + ECSensor.TempChipset, ECSensor.TempCPU, ECSensor.TempMB, + ECSensor.TempTSensor, ECSensor.TempVrm, + ECSensor.FanCPUOpt, ECSensor.FanChipset, ECSensor.CurrCPU, ECSensor.VoltageCPU + ), + new(Model.ROG_CROSSHAIR_VIII_IMPACT, BoardFamily.Amd500, + ECSensor.TempChipset, ECSensor.TempCPU, ECSensor.TempMB, + ECSensor.TempTSensor, ECSensor.TempVrm, + ECSensor.FanChipset, ECSensor.CurrCPU, ECSensor.VoltageCPU + ), + new(Model.ROG_STRIX_B550_E_GAMING, BoardFamily.Amd500, + ECSensor.TempChipset, ECSensor.TempCPU, ECSensor.TempMB, + ECSensor.TempTSensor, ECSensor.TempVrm, ECSensor.FanCPUOpt + ), + new(Model.ROG_STRIX_B550_I_GAMING, BoardFamily.Amd500, + ECSensor.TempChipset, ECSensor.TempCPU, ECSensor.TempMB, + ECSensor.TempTSensor, ECSensor.TempVrm, + ECSensor.FanVrmHS, ECSensor.CurrCPU, ECSensor.VoltageCPU + ), + new(Model.ROG_STRIX_X570_E_GAMING, BoardFamily.Amd500, + ECSensor.TempChipset, ECSensor.TempCPU, ECSensor.TempMB, + ECSensor.TempTSensor, ECSensor.TempVrm, + ECSensor.FanChipset, ECSensor.CurrCPU, ECSensor.VoltageCPU + ), + new(Model.ROG_STRIX_X570_F_GAMING, BoardFamily.Amd500, + ECSensor.TempChipset, ECSensor.TempCPU, ECSensor.TempMB, + ECSensor.TempTSensor, ECSensor.FanChipset + ), + new(Model.ROG_STRIX_X570_I_GAMING, BoardFamily.Amd500, + ECSensor.TempTSensor, ECSensor.FanVrmHS, ECSensor.FanChipset, + ECSensor.CurrCPU, ECSensor.VoltageCPU + ), + new(Model.ROG_STRIX_Z690_A_GAMING_WIFI_D4, BoardFamily.Intel600, + ECSensor.TempTSensor, ECSensor.TempVrm + ), + new(Model.Z170_A, BoardFamily.Intel100, + ECSensor.TempTSensor, ECSensor.TempChipset, ECSensor.FanWaterPump, + ECSensor.CurrCPU, ECSensor.VoltageCPU + ), + }; private readonly IReadOnlyList _sources; private readonly List _sensors; @@ -192,18 +244,19 @@ namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc.EC internal static EmbeddedController Create(Model model, ISettings settings) { - if (_boardSensors.TryGetValue(model, out ECSensor[] sensors)) + var boards = _boards.Where(b => b.Models.Contains(model)).ToList(); + if (boards.Count == 0) + return null; + if (boards.Count > 1) + throw new MultipleBoardRecordsFoundException(model.ToString()); + BoardInfo board = boards[0]; + var sources = board.Sensors.Select(ecs => _knownSensors[board.Family][ecs]); + + return Environment.OSVersion.Platform switch { - var sources = sensors.Select(ecs => _knownSensors[ecs]); - - return Environment.OSVersion.Platform switch - { - PlatformID.Win32NT => new WindowsEmbeddedController(sources, settings), - _ => null - }; - } - - return null; + PlatformID.Win32NT => new WindowsEmbeddedController(sources, settings), + _ => null + }; } public override void Update() @@ -291,5 +344,15 @@ namespace LibreHardwareMonitor.Hardware.Motherboard.Lpc.EC public class IOException: System.IO.IOException { public IOException(string message): base($"ACPI embedded controller I/O error: {message}") { } } + + public class BadConfigurationException: System.Exception + { + public BadConfigurationException(string message): base(message) { } + } + + public class MultipleBoardRecordsFoundException : BadConfigurationException + { + public MultipleBoardRecordsFoundException(string model) : base($"Multiple board records refer to the same model '{model}'") { } + } } } diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Model.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Model.cs index dc4dce9..dc8b3bc 100644 --- a/LibreHardwareMonitorLib/Hardware/Motherboard/Model.cs +++ b/LibreHardwareMonitorLib/Hardware/Motherboard/Model.cs @@ -62,6 +62,7 @@ namespace LibreHardwareMonitor.Hardware.Motherboard P8Z77_V, P9X79, PRIME_X370_PRO, + PRIME_X470_PRO, PRIME_X570_PRO, PRO_WS_X570_ACE, RAMPAGE_EXTREME,