From 701e8ad5143d6d249006429cfd12511ccd01d6c6 Mon Sep 17 00:00:00 2001 From: Maximilian Rehkopf Date: Tue, 13 Jun 2023 13:44:24 +0200 Subject: [PATCH] Add support for IT87952E EC on Gigabyte boards (#1091) * Rename IT8795E to IT87952E IT8795E and IT87952E are distinct chips (with their own IC markings). The IT8795E, as the IT8791E and IT8792E, reports chip ID 0x8733 whereas the IT87952E identifies as 0x8695. * Gigabyte EC: Fix typo in LPC register restore When the AMD LPC Bridge registers are restored after configuring memory mapping, restore the correct value for the "Memory Address for LPC target cycles" register. * Add IT87952E fan control for Gigabyte boards IT87952E (ID 0x8695) has a third byte in SuperIO config space (LDN 0x0F) that determines more bits of the host address for LPC memory mapping. Also the base address for Gigabyte boards is 0xFC000000 instead of 0xFF000000 (as is the case with IT8790/1/2/5). This should make additional fan controls work on Gigabyte mainboards where the settings had no effect previously, e.g: X570S AORUS MASTER and X670E AORUS MASTER. (cf. Issue #251) It does not yet work for Intel boards as the LPC bridge requires different programming. * Update LpcIO.cs --------- Co-authored-by: PhyxionNL <7643972+PhyxionNL@users.noreply.github.com> --- .../Hardware/Motherboard/Lpc/Chip.cs | 8 +++--- .../Motherboard/Lpc/GigabyteController.cs | 2 +- .../Hardware/Motherboard/Lpc/IT87XX.cs | 6 ++--- .../Hardware/Motherboard/Lpc/LpcIO.cs | 25 +++++++++++++++---- .../Hardware/Motherboard/SuperIOHardware.cs | 2 +- 5 files changed, 29 insertions(+), 14 deletions(-) diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/Chip.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/Chip.cs index b929eb9..7a8c336 100644 --- a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/Chip.cs +++ b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/Chip.cs @@ -48,8 +48,8 @@ internal enum Chip : ushort IT8771E = 0x8771, IT8772E = 0x8772, IT8790E = 0x8790, - IT8792E = 0x8733, // Could also be IT8791E - IT8795E = 0x8695, + IT8792E = 0x8733, // Could also be IT8791E, IT8795E + IT87952E = 0x8695, NCT610XD = 0xC452, NCT6771F = 0xB470, @@ -120,8 +120,8 @@ internal class ChipName case Chip.IT8771E: return "ITE IT8771E"; case Chip.IT8772E: return "ITE IT8772E"; case Chip.IT8790E: return "ITE IT8790E"; - case Chip.IT8792E: return "ITE IT8791E/IT8792E"; - case Chip.IT8795E: return "ITE IT8795E"; + case Chip.IT8792E: return "ITE IT8791E/IT8792E/IT8795E"; + case Chip.IT87952E: return "ITE IT87952E"; case Chip.NCT610XD: return "Nuvoton NCT6102D/NCT6104D/NCT6106D"; case Chip.NCT6771F: return "Nuvoton NCT6771F"; diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/GigabyteController.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/GigabyteController.cs index 5676416..9a6e1dc 100644 --- a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/GigabyteController.cs +++ b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/GigabyteController.cs @@ -95,7 +95,7 @@ internal class GigabyteController if (!originalMmIoEnabled) { Ring0.WritePciConfig(amdIsaBridgeAddress, ioOrMemoryPortDecodeEnableRegister, originalDecodeEnableRegister); - Ring0.WritePciConfig(amdIsaBridgeAddress, pciMemoryAddressForLpcTargetCyclesRegister, originalRomAddressRegister); + Ring0.WritePciConfig(amdIsaBridgeAddress, pciMemoryAddressForLpcTargetCyclesRegister, originalPciMemoryAddressRegister); Ring0.WritePciConfig(amdIsaBridgeAddress, romAddressRange2Register, originalRomAddressRegister); } diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/IT87XX.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/IT87XX.cs index 0a1d5dc..6b72ae7 100644 --- a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/IT87XX.cs +++ b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/IT87XX.cs @@ -88,7 +88,7 @@ internal class IT87XX : ISuperIO Chip.IT8686E or Chip.IT8688E or Chip.IT8689E or - Chip.IT8795E or + Chip.IT87952E or Chip.IT8628E or Chip.IT8625E or Chip.IT8620E or @@ -148,7 +148,7 @@ internal class IT87XX : ISuperIO Controls = new float?[6]; break; - case Chip.IT8795E: + case Chip.IT87952E: Voltages = new float?[6]; Temperatures = new float?[3]; Fans = new float?[3]; @@ -191,7 +191,7 @@ internal class IT87XX : ISuperIO _voltageGain = chip switch { Chip.IT8613E or Chip.IT8620E or Chip.IT8628E or Chip.IT8631E or Chip.IT8721F or Chip.IT8728F or Chip.IT8771E or Chip.IT8772E or Chip.IT8686E or Chip.IT8688E or Chip.IT8689E => 0.012f, - Chip.IT8625E or Chip.IT8792E or Chip.IT8795E => 0.011f, + Chip.IT8625E or Chip.IT8792E or Chip.IT87952E => 0.011f, Chip.IT8655E or Chip.IT8665E => 0.0109f, _ => 0.016f }; diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/LpcIO.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/LpcIO.cs index 9d72205..4b38f7b 100644 --- a/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/LpcIO.cs +++ b/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/LpcIO.cs @@ -1,4 +1,4 @@ -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. +// This Source Code Form is subject to the terms of the Mozilla Public 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/. // Copyright (C) LibreHardwareMonitor and Contributors. // Partial Copyright (C) Michael Möller and Contributors. @@ -563,7 +563,7 @@ internal class LpcIO 0x8772 => Chip.IT8772E, 0x8790 => Chip.IT8790E, 0x8733 => Chip.IT8792E, - 0x8695 => Chip.IT8795E, + 0x8695 => Chip.IT87952E, _ => Chip.Unknown }; @@ -642,7 +642,7 @@ internal class LpcIO // The controller only affects the 2nd ITE chip if present, and only a few // models are known to use this controller. // IT8795E likely to need this too, but may use different registers. - if (motherboard.Manufacturer != Manufacturer.Gigabyte || port.RegisterPort != 0x4E || chip is not (Chip.IT8790E or Chip.IT8792E)) + if (motherboard.Manufacturer != Manufacturer.Gigabyte || port.RegisterPort != 0x4E || chip is not (Chip.IT8790E or Chip.IT8792E or Chip.IT87952E)) return null; port.Select(IT87XX_SMFI_LDN); @@ -657,15 +657,29 @@ internal class LpcIO return null; // Read the host RAM address that maps to the Embedded Controller's RAM (two registers). + uint addressHi = 0; + uint addressHiVerify = 0; uint address = port.ReadWord(IT87_SMFI_HLPC_RAM_BASE_ADDRESS_REGISTER); + if (chip == Chip.IT87952E) + addressHi = port.ReadByte(IT87_SMFI_HLPC_RAM_BASE_ADDRESS_REGISTER_HIGH); + Thread.Sleep(1); uint addressVerify = port.ReadWord(IT87_SMFI_HLPC_RAM_BASE_ADDRESS_REGISTER); + if (chip == Chip.IT87952E) + addressHiVerify = port.ReadByte(IT87_SMFI_HLPC_RAM_BASE_ADDRESS_REGISTER_HIGH); - if (address != addressVerify) + if ((address != addressVerify) || (addressHi != addressHiVerify)) return null; // Address is xryy, Host Address is FFyyx000 - uint hostAddress = 0xFF000000 | (address & 0xF000) | (address & 0xFF) << 0x10; + // For IT87952E, Address is rzxryy, Host Address is (0xFC000000 | 0x0zyyx000) + uint hostAddress; + if (chip == Chip.IT87952E) + hostAddress = 0xFC000000; + else + hostAddress = 0xFF000000; + + hostAddress |= (address & 0xF000) | ((address & 0xFF) << 16) | ((addressHi & 0xF) << 24); return new GigabyteController(hostAddress, DetectVendor()); @@ -702,6 +716,7 @@ internal class LpcIO private const byte FINTEK_VENDOR_ID_REGISTER = 0x23; private const byte IT87_CHIP_VERSION_REGISTER = 0x22; private const byte IT87_SMFI_HLPC_RAM_BASE_ADDRESS_REGISTER = 0xF5; + private const byte IT87_SMFI_HLPC_RAM_BASE_ADDRESS_REGISTER_HIGH = 0xFC; private const byte IT87_LD_ACTIVE_REGISTER = 0x30; private readonly ushort[] REGISTER_PORTS = { 0x2E, 0x4E }; diff --git a/LibreHardwareMonitorLib/Hardware/Motherboard/SuperIOHardware.cs b/LibreHardwareMonitorLib/Hardware/Motherboard/SuperIOHardware.cs index 8a992f2..3591b6f 100644 --- a/LibreHardwareMonitorLib/Hardware/Motherboard/SuperIOHardware.cs +++ b/LibreHardwareMonitorLib/Hardware/Motherboard/SuperIOHardware.cs @@ -233,7 +233,7 @@ internal sealed class SuperIOHardware : Hardware GetIteConfigurationsB(superIO, manufacturer, model, v, t, f, c); break; - case Chip.IT8795E: + case Chip.IT87952E: case Chip.IT8792E: case Chip.IT8790E: GetIteConfigurationsC(superIO, manufacturer, model, v, t, f, c);