REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171
Adds the following files: * IpBlock/Pmc/IncludePrivate * IpBlock/Pmc/Library * IpBlock/Pmc/LibraryPrivate Cc: Sai Chaganty <rangasai.v.chaga...@intel.com> Cc: Nate DeSimone <nathaniel.l.desim...@intel.com> Signed-off-by: Heng Luo <heng....@intel.com> --- Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/IncludePrivate/Library/PmcPrivateLib.h | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/IncludePrivate/Register/PmcRegsVer2.h | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/Library/PeiDxeSmmPmcLib/PeiDxeSmmPmcLib.inf | 42 ++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/Library/PeiDxeSmmPmcLib/PmcLib.c | 545 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibVer2.inf | 39 +++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibWithS3.inf | 40 ++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PmcPrivateLib.c | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PmcPrivateLibWithS3.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 1126 insertions(+) diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/IncludePrivate/Library/PmcPrivateLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/IncludePrivate/Library/PmcPrivateLib.h new file mode 100644 index 0000000000..0f2f251d57 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/IncludePrivate/Library/PmcPrivateLib.h @@ -0,0 +1,120 @@ +/** @file + Header file for private PmcLib. + + Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#ifndef _PMC_PRIVATE_LIB_H_ +#define _PMC_PRIVATE_LIB_H_ + +#include <Library/PmcLib.h> +#include "Register/PmcRegs.h" + +/** + This function checks if GbE device is supported (not disabled by fuse) + + @retval GbE support state +**/ +BOOLEAN +PmcIsGbeSupported ( + VOID + ); + +/** + This function checks if LAN wake from DeepSx is enabled + + @retval Lan Wake state +**/ +BOOLEAN +PmcIsLanDeepSxWakeEnabled ( + VOID + ); + +/** + This function sets SMI Lock with S3 Boot Script programming +**/ +VOID +PmcLockSmiWithS3BootScript ( + VOID + ); + +/** + This function sets eSPI SMI Lock + @attention This function must be called after eSPI SMI generation has been enabled. + This setting is required in all boot modes and before EndOfDxe. + If set value will be restored upon S3 resume by bootscript. +**/ +VOID +PmcLockEspiSmiWithS3BootScript ( + VOID + ); + +/** + This function checks if eSPI SMI Lock is set + + @retval eSPI SMI Lock state +**/ +BOOLEAN +PmcIsEspiSmiLockSet ( + VOID + ); + +typedef enum { + PmcSwSmiRate1p5ms = 0, + PmcSwSmiRate16ms, + PmcSwSmiRate32ms, + PmcSwSmiRate64ms +} PMC_SWSMI_RATE; + +/** + This function sets SW SMI Rate. + + @param[in] SwSmiRate Refer to PMC_SWSMI_RATE for possible values +**/ +VOID +PmcSetSwSmiRate ( + IN PMC_SWSMI_RATE SwSmiRate + ); + +typedef enum { + PmcPeriodicSmiRate8s = 0, + PmcPeriodicSmiRate16s, + PmcPeriodicSmiRate32s, + PmcPeriodicSmiRate64s +} PMC_PERIODIC_SMI_RATE; + +/** + This function sets Periodic SMI Rate. + + @param[in] PeriodicSmiRate Refer to PMC_PERIODIC_SMI_RATE for possible values +**/ +VOID +PmcSetPeriodicSmiRate ( + IN PMC_PERIODIC_SMI_RATE PeriodicSmiRate + ); + +/** + This function reads Power Button Level + + @retval State of PWRBTN# signal (0: Low, 1: High) +**/ +UINT8 +PmcGetPwrBtnLevel ( + VOID + ); + +/** + This function gets Group to GPE0 configuration + + @param[out] GpeDw0Value GPIO Group to GPE_DW0 assignment + @param[out] GpeDw1Value GPIO Group to GPE_DW1 assignment + @param[out] GpeDw2Value GPIO Group to GPE_DW2 assignment +**/ +VOID +PmcGetGpioGpe ( + OUT UINT32 *GpeDw0Value, + OUT UINT32 *GpeDw1Value, + OUT UINT32 *GpeDw2Value + ); + +#endif // _PMC_PRIVATE_LIB_H_ diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/IncludePrivate/Register/PmcRegsVer2.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/IncludePrivate/Register/PmcRegsVer2.h new file mode 100644 index 0000000000..986173dd7d --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/IncludePrivate/Register/PmcRegsVer2.h @@ -0,0 +1,52 @@ +/** @file + Register names for Ver2 PCH PMC device + + Conventions: + + - Register definition format: + Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpace_RegisterName + - Prefix: + Definitions beginning with "R_" are registers + Definitions beginning with "B_" are bits within registers + Definitions beginning with "V_" are meaningful values within the bits + Definitions beginning with "S_" are register size + Definitions beginning with "N_" are the bit position + - [GenerationName]: + Three letter acronym of the generation is used (e.g. SKL,KBL,CNL etc.). + Register name without GenerationName applies to all generations. + - [ComponentName]: + This field indicates the component name that the register belongs to (e.g. PCH, SA etc.) + Register name without ComponentName applies to all components. + Register that is specific to -LP denoted by "_PCH_LP_" in component name. + - SubsystemName: + This field indicates the subsystem name of the component that the register belongs to + (e.g. PCIE, USB, SATA, GPIO, PMC etc.). + - RegisterSpace: + MEM - MMIO space register of subsystem. + IO - IO space register of subsystem. + PCR - Private configuration register of subsystem. + CFG - PCI configuration space register of subsystem. + - RegisterName: + Full register name. + + Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#ifndef _PCH_REGS_PMC_TGL_H_ +#define _PCH_REGS_PMC_TGL_H_ + +// +// PWRM Registers +// +#define V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_B 0x0 +#define V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_A 0x2 +#define V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_R 0x3 +#define V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPD 0x4 +#define V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_S 0x5 +#define V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_H 0x6 +#define V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_D 0x7 +#define V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_F 0xA +#define V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_C 0xB +#define V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_E 0xC + +#endif // _PCH_REGS_PMC_TGL_H_ diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/Library/PeiDxeSmmPmcLib/PeiDxeSmmPmcLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/Library/PeiDxeSmmPmcLib/PeiDxeSmmPmcLib.inf new file mode 100644 index 0000000000..eba6db767c --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/Library/PeiDxeSmmPmcLib/PeiDxeSmmPmcLib.inf @@ -0,0 +1,42 @@ +## @file +# PEI/DXE/SMM PCH PMC Lib. +# +# All function in this library is available for PEI, DXE, and SMM, +# But do not support UEFI RUNTIME environment call. +# +# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + + +[Defines] +INF_VERSION = 0x00010017 +BASE_NAME = PeiDxeSmmPmcLib +FILE_GUID = 9D60C364-5086-41E3-BC9D-C62AB7233DBF +VERSION_STRING = 1.0 +MODULE_TYPE = BASE +LIBRARY_CLASS = PmcLib + + +[LibraryClasses] +BaseLib +IoLib +DebugLib +PciSegmentLib +PchCycleDecodingLib +PchPcrLib +PchInfoLib +BaseMemoryLib + +[Packages] +MdePkg/MdePkg.dec +TigerlakeSiliconPkg/SiPkg.dec + + +[Pcd] +gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress +gSiPkgTokenSpaceGuid.PcdTcoBaseAddress + +[Sources] +PmcLib.c diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/Library/PeiDxeSmmPmcLib/PmcLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/Library/PeiDxeSmmPmcLib/PmcLib.c new file mode 100644 index 0000000000..78e596b268 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/Library/PeiDxeSmmPmcLib/PmcLib.c @@ -0,0 +1,545 @@ +/** @file + PCH PMC Library. + All function in this library is available for PEI, DXE, and SMM, + But do not support UEFI RUNTIME environment call. + + Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <Base.h> +#include <Uefi/UefiBaseType.h> +#include <Library/IoLib.h> +#include <Library/DebugLib.h> +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/PciSegmentLib.h> +#include <Library/PchCycleDecodingLib.h> +#include <Library/PmcLib.h> +#include <Library/PchPcrLib.h> +#include <Library/PchInfoLib.h> +#include <PchReservedResources.h> +#include <Register/PmcRegs.h> +#include <Register/PchRegs.h> + +/** + Get PCH ACPI base address. + + @retval Address Address of PWRM base address. +**/ +UINT16 +PmcGetAcpiBase ( + VOID + ) +{ + return PcdGet16 (PcdAcpiBaseAddress); +} + +/** + Get PCH PWRM base address. + + @retval Address Address of PWRM base address. +**/ +UINT32 +PmcGetPwrmBase ( + VOID + ) +{ + return PCH_PWRM_BASE_ADDRESS; +} + +/** + This function enables Power Button SMI +**/ +VOID +PmcEnablePowerButtonSmi ( + VOID + ) +{ + IoOr16 (PmcGetAcpiBase () + R_ACPI_IO_PM1_EN, B_ACPI_IO_PM1_EN_PWRBTN); +} + +/** + This function disables Power Button SMI +**/ +VOID +PmcDisablePowerButtonSmi ( + VOID + ) +{ + IoAnd16 (PmcGetAcpiBase () + R_ACPI_IO_PM1_EN, (UINT16)~B_ACPI_IO_PM1_EN_PWRBTN); +} + +/** + This function reads PM Timer Count driven by 3.579545 MHz clock + + @retval PM Timer Count +**/ +UINT32 +PmcGetTimerCount ( + VOID + ) +{ + return IoRead32 (PmcGetAcpiBase () + R_ACPI_IO_PM1_TMR) & B_ACPI_IO_PM1_TMR_VAL; +} + +/** + Get Sleep Type that platform has waken from + + @retval SleepType Sleep Type +**/ +PMC_SLEEP_STATE +PmcGetSleepTypeAfterWake ( + VOID + ) +{ + UINT16 AcpiBase; + UINT32 PmconA; + + AcpiBase = PmcGetAcpiBase (); + PmconA = MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A); + + DEBUG ((DEBUG_INFO, "PWRM_PMCON_A = 0x%x\n", PmconA)); + + // + // If Global Reset Status, Power Failure. Host Reset Status bits are set, return S5 State + // + if ((PmconA & (B_PMC_PWRM_GEN_PMCON_A_GBL_RST_STS | B_PMC_PWRM_GEN_PMCON_A_PWR_FLR | B_PMC_PWRM_GEN_PMCON_A_HOST_RST_STS)) != 0) { + return PmcNotASleepState; + } + + if (IoRead16 (AcpiBase + R_ACPI_IO_PM1_STS) & B_ACPI_IO_PM1_STS_WAK) { + switch (IoRead16 (AcpiBase + R_ACPI_IO_PM1_CNT) & B_ACPI_IO_PM1_CNT_SLP_TYP) { + case V_ACPI_IO_PM1_CNT_S0: + return PmcInS0State; + + case V_ACPI_IO_PM1_CNT_S1: + return PmcS1SleepState; + + case V_ACPI_IO_PM1_CNT_S3: + return PmcS3SleepState; + + case V_ACPI_IO_PM1_CNT_S4: + return PmcS4SleepState; + + case V_ACPI_IO_PM1_CNT_S5: + return PmcS5SleepState; + + default: + ASSERT (FALSE); + return PmcUndefinedState; + } + } else { + return PmcNotASleepState; + } +} + +/** + Clear PMC Wake Status +**/ +VOID +PmcClearWakeStatus ( + VOID + ) +{ + IoWrite16 (PmcGetAcpiBase () + R_ACPI_IO_PM1_STS, B_ACPI_IO_PM1_STS_WAK); +} + +/** + Configure sleep state + + @param[in] SleepState S0/S1/S3/S4/S5, refer to PMC_SLEEP_STATE +**/ +VOID +PmcSetSleepState ( + PMC_SLEEP_STATE SleepState + ) +{ + UINT16 Data16; + + switch (SleepState) { + case PmcInS0State: + Data16 = V_ACPI_IO_PM1_CNT_S0; + break; + + case PmcS1SleepState: + Data16 = V_ACPI_IO_PM1_CNT_S1; + break; + + case PmcS3SleepState: + Data16 = V_ACPI_IO_PM1_CNT_S3; + break; + + case PmcS4SleepState: + Data16 = V_ACPI_IO_PM1_CNT_S4; + break; + + case PmcS5SleepState: + Data16 = V_ACPI_IO_PM1_CNT_S5; + break; + + default: + ASSERT (FALSE); + return; + + } + IoAndThenOr16 (PmcGetAcpiBase () + R_ACPI_IO_PM1_CNT, (UINT16) ~B_ACPI_IO_PM1_CNT_SLP_TYP, Data16); +} + +/** + Check if platform boots after shutdown caused by power button override event + + @retval TRUE Power Button Override occurred in last system boot + @retval FALSE Power Button Override didn't occur +**/ +BOOLEAN +PmcIsPowerButtonOverrideDetected ( + VOID + ) +{ + return ((IoRead16 (PmcGetAcpiBase () + R_ACPI_IO_PM1_STS) & B_ACPI_IO_PM1_STS_PRBTNOR) != 0); +} + +/** + This function sets tPCH25 timing + + @param[in] TimingValue tPCH25 timing value (10us, 100us, 1ms, 10ms) +**/ +VOID +PmcSetTPch25Timing ( + IN PMC_TPCH25_TIMING TimingValue + ) +{ + ASSERT (TimingValue <= PmcTPch25_10ms); + + MmioAndThenOr32 ( + (UINTN) (PmcGetPwrmBase () + R_PMC_PWRM_CFG), + (UINT32)~(B_PMC_PWRM_CFG_TIMING_TPCH25), + TimingValue + ); +} + +/** + This function checks if RTC Power Failure occurred by + reading RTC_PWR_FLR bit + + @retval RTC Power Failure state: TRUE - Battery is always present. + FALSE - CMOS is cleared. +**/ +BOOLEAN +PmcIsRtcBatteryGood ( + VOID + ) +{ + return ((MmioRead8 (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_B) & B_PMC_PWRM_GEN_PMCON_B_RTC_PWR_STS) == 0); +} + +/** + This function checks if Power Failure occurred by + reading PWR_FLR bit + + @retval Power Failure state +**/ +BOOLEAN +PmcIsPowerFailureDetected ( + VOID + ) +{ + return ((MmioRead16 (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A) & B_PMC_PWRM_GEN_PMCON_A_PWR_FLR) != 0); +} + +/** + This function checks if Power Failure occurred by + reading SUS_PWR_FLR bit + + @retval SUS Power Failure state +**/ +BOOLEAN +PmcIsSusPowerFailureDetected ( + VOID + ) +{ + return ((MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A) & B_PMC_PWRM_GEN_PMCON_A_SUS_PWR_FLR) != 0); +} + +/** + This function clears Power Failure status (PWR_FLR) +**/ +VOID +PmcClearPowerFailureStatus ( + VOID + ) +{ + // + // Write 1 to clear PWR_FLR + // Avoid clearing other W1C bits + // + MmioAndThenOr8 ( + PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A + 1, + (UINT8) ~(B_PMC_PWRM_GEN_PMCON_A_HOST_RST_STS >> 8), + B_PMC_PWRM_GEN_PMCON_A_PWR_FLR >> 8 + ); +} + +/** + This function clears Global Reset status (GBL_RST_STS) +**/ +VOID +PmcClearGlobalResetStatus ( + VOID + ) +{ + // + // Write 1 to clear GBL_RST_STS + // Avoid clearing other W1C bits + // + MmioAndThenOr8 ( + PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A + 3, + (UINT8) ~0, + B_PMC_PWRM_GEN_PMCON_A_GBL_RST_STS >> 24 + ); +} + +/** + This function clears Host Reset status (HOST_RST_STS) +**/ +VOID +PmcClearHostResetStatus ( + VOID + ) +{ + // + // Write 1 to clear HOST_RST_STS + // Avoid clearing other W1C bits + // + MmioAndThenOr8 ( + PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A + 1, + (UINT8) ~(B_PMC_PWRM_GEN_PMCON_A_PWR_FLR >> 8), + B_PMC_PWRM_GEN_PMCON_A_HOST_RST_STS >> 8 + ); +} + +/** + This function clears SUS Power Failure status (SUS_PWR_FLR) +**/ +VOID +PmcClearSusPowerFailureStatus ( + VOID + ) +{ + // + // BIOS clears this bit by writing a '1' to it. + // Take care of other fields, so we don't clear them accidentally. + // + MmioAndThenOr8 ( + PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A + 2, + (UINT8) ~(B_PMC_PWRM_GEN_PMCON_A_MS4V >> 16), + B_PMC_PWRM_GEN_PMCON_A_SUS_PWR_FLR >> 16 + ); +} + +/** + This function sets state to which platform will get after power is reapplied + + @param[in] PowerStateAfterG3 0: S0 state (boot) + 1: S5/S4 State +**/ +VOID +PmcSetPlatformStateAfterPowerFailure ( + IN UINT8 PowerStateAfterG3 + ) +{ + UINT32 PchPwrmBase; + + PchPwrmBase = PmcGetPwrmBase (); + + if (PowerStateAfterG3) { + MmioOr8 (PchPwrmBase + R_PMC_PWRM_GEN_PMCON_A, B_PMC_PWRM_GEN_PMCON_A_AFTERG3_EN); + } else { + MmioAnd8 (PchPwrmBase + R_PMC_PWRM_GEN_PMCON_A, (UINT8)~B_PMC_PWRM_GEN_PMCON_A_AFTERG3_EN); + } +} + +/** + This function will set the DISB - DRAM Initialization Scratchpad Bit. +**/ +VOID +PmcSetDramInitScratchpad ( + VOID + ) +{ + // + // Set B_CNL_PCH_PWRM_GEN_PMCON_A_DISB. + // NOTE: Byte access and not clear BIT18 and BIT16 (W1C bits) + // + MmioAndThenOr8 ( + PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A + 2, + (UINT8) ~((B_PMC_PWRM_GEN_PMCON_A_MS4V | B_PMC_PWRM_GEN_PMCON_A_SUS_PWR_FLR) >> 16), + B_PMC_PWRM_GEN_PMCON_A_DISB >> 16 + ); +} + +/** + Check global SMI enable is set + + @retval TRUE Global SMI enable is set + FALSE Global SMI enable is not set +**/ +BOOLEAN +PmcIsGblSmiEn ( + VOID + ) +{ + return !!(IoRead32 (PmcGetAcpiBase () + R_ACPI_IO_SMI_EN) & B_ACPI_IO_SMI_EN_GBL_SMI); +} + +/** + This function checks if SMI Lock is set + + @retval SMI Lock state +**/ +BOOLEAN +PmcIsSmiLockSet ( + VOID + ) +{ + return ((MmioRead8 ((UINTN) (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_B)) & B_PMC_PWRM_GEN_PMCON_B_SMI_LOCK) != 0); +} + +/** + This function checks if Debug Mode is locked + + @retval Debug Mode Lock state +**/ +BOOLEAN +PmcIsDebugModeLocked ( + VOID + ) +{ + // + // Get lock info from PWRMBASE + PM_CFG + // + return ((MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_CFG) & B_PMC_PWRM_CFG_DBG_MODE_LOCK) != 0); +} + +/** + Check TCO second timeout status. + + @retval TRUE TCO reboot happened. + @retval FALSE TCO reboot didn't happen. +**/ +BOOLEAN +TcoSecondToHappened ( + VOID + ) +{ + /// + /// Read the Second TO status bit + /// + if ((IoRead8 (PcdGet16 (PcdTcoBaseAddress) + R_TCO_IO_TCO2_STS) & R_TCO_IO_TCO2_STS) != 0) { + return TRUE; + } else { + return FALSE; + } +} + +/** + This function clears the Second TO status bit +**/ +VOID +TcoClearSecondToStatus ( + VOID + ) +{ + IoWrite8 (PcdGet16 (PcdTcoBaseAddress) + R_TCO_IO_TCO2_STS, B_TCO_IO_TCO2_STS_SECOND_TO); +} + +/** + Check TCO SMI ENABLE is locked + + @retval TRUE TCO SMI ENABLE is locked + FALSE TCO SMI ENABLE is not locked +**/ +BOOLEAN +TcoIsSmiLock ( + VOID + ) +{ + return !!(IoRead16 (PcdGet16 (PcdTcoBaseAddress) + R_TCO_IO_TCO1_CNT) & B_TCO_IO_TCO1_CNT_LOCK); +} + +/** + Check if user wants to turn off in PEI phase and power it off + CAUTION: this function will potentially turn off your system +**/ +VOID +CheckPowerOffNow ( + VOID + ) +{ + UINT16 ABase; + UINT16 Pm1Sts; + + ABase = PmcGetAcpiBase (); + + // + // Read and check the ACPI registers + // + Pm1Sts = IoRead16 (ABase + R_ACPI_IO_PM1_STS); + + DEBUG ((DEBUG_ERROR, "CheckPowerOffNow ()- Pm1Sts= 0x%04x\n", Pm1Sts)); + + if ((Pm1Sts & B_ACPI_IO_PM1_STS_PWRBTN) != 0) { + IoWrite16 (ABase + R_ACPI_IO_PM1_STS, B_ACPI_IO_PM1_STS_PWRBTN); + IoWrite16 (ABase + R_ACPI_IO_PM1_CNT, V_ACPI_IO_PM1_CNT_S5); + IoWrite16 (ABase + R_ACPI_IO_PM1_CNT, V_ACPI_IO_PM1_CNT_S5 | B_ACPI_IO_PM1_CNT_SLP_EN); + } +} + +/** + Clear any SMI status or wake status. +**/ +VOID +ClearSmiAndWake ( + VOID + ) +{ + UINT16 ABase; + UINT16 Pm1Sts; + + ABase = PmcGetAcpiBase (); + + // + // Clear any SMI or wake state from the boot + // + Pm1Sts = B_ACPI_IO_PM1_STS_PWRBTN; + + IoWrite16 (ABase + R_ACPI_IO_PM1_STS, Pm1Sts); + + // + // Clear the GPE and PM enable + // + IoWrite16 (ABase + R_ACPI_IO_PM1_EN, 0); + IoWrite32 (ABase + R_ACPI_IO_GPE0_EN_127_96, 0); +} + + +/** + Function to check if Dirty Warm Reset occurs + (Global Reset has been converted to Host Reset) + + @reval TRUE DWR occurs + @reval FALSE Normal boot flow +**/ +BOOLEAN +PmcIsDwrBootMode ( + VOID + ) +{ + UINT32 PchPwrmBase; + + PchPwrmBase = PmcGetPwrmBase (); + ASSERT (PchPwrmBase != 0); + + return !!(MmioRead32 (PchPwrmBase + R_PMC_PWRM_HPR_CAUSE0) & B_PMC_PWRM_HPR_CAUSE0_GBL_TO_HOST); +} diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibVer2.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibVer2.inf new file mode 100644 index 0000000000..2bd57b79f0 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibVer2.inf @@ -0,0 +1,39 @@ +## @file +# PEI/DXE/SMM PCH PMC Private Lib Ver2. +# +# All function in this library is available for PEI, DXE, and SMM, +# But do not support UEFI RUNTIME environment call. +# +# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + + +[Defines] +INF_VERSION = 0x00010017 +BASE_NAME = PeiDxeSmmPmcPrivateLibVer2 +FILE_GUID = EB69B12B-6D4C-4B12-BB31-66CBCC4C1DC7 +VERSION_STRING = 1.0 +MODULE_TYPE = BASE +LIBRARY_CLASS = PmcPrivateLib + + +[LibraryClasses] +BaseLib +IoLib +DebugLib +PmcLib + +[Packages] +MdePkg/MdePkg.dec +TigerlakeSiliconPkg/SiPkg.dec + + +[Pcd] +gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress + +[FixedPcd] + +[Sources] +PmcPrivateLib.c diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibWithS3.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibWithS3.inf new file mode 100644 index 0000000000..72a21cfe14 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibWithS3.inf @@ -0,0 +1,40 @@ +## @file +# PEI/DXE/SMM PCH private PMC Lib. +# This part of PMC lib includes S3BootScript support +# +# All function in this library is available for PEI, DXE, and SMM, +# But do not support UEFI RUNTIME environment call. +# +# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + + +[Defines] +INF_VERSION = 0x00010017 +BASE_NAME = PeiDxeSmmPmcPrivateLibWithS3 +FILE_GUID = 5890CA5A-1955-4A02-A09C-01E4150606CC +VERSION_STRING = 1.0 +MODULE_TYPE = BASE +LIBRARY_CLASS = PmcPrivateLibWithS3 + + +[LibraryClasses] +BaseLib +IoLib +DebugLib +PciSegmentLib +PmcLib +PcdLib +S3BootScriptLib +PchPciBdfLib + + +[Packages] +MdePkg/MdePkg.dec +TigerlakeSiliconPkg/SiPkg.dec + + +[Sources] +PmcPrivateLibWithS3.c diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PmcPrivateLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PmcPrivateLib.c new file mode 100644 index 0000000000..4f04765886 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PmcPrivateLib.c @@ -0,0 +1,166 @@ +/** @file + PCH private PMC Library for all PCH generations. + All function in this library is available for PEI, DXE, and SMM, + But do not support UEFI RUNTIME environment call. + + Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <Base.h> +#include <Uefi/UefiBaseType.h> +#include <Library/IoLib.h> +#include <Library/DebugLib.h> +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/PmcLib.h> +#include <Library/PciSegmentLib.h> +#include <Library/PchPcrLib.h> +#include <Library/PchInfoLib.h> +#include <Library/PmcPrivateLib.h> + +/** + This function checks if GbE device is supported (not disabled by fuse) + + @retval GbE support state +**/ +BOOLEAN +PmcIsGbeSupported ( + VOID + ) +{ + // + // Get fuse info from PWRMBASE + FUSE_SS_DIS_RD_2 + // + return ((MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_FUSE_DIS_RD_2) & B_PMC_PWRM_FUSE_DIS_RD_2_GBE_FUSE_SS_DIS) == 0); +} + +/** + This function checks if LAN wake from DeepSx is enabled + + @retval Lan Wake state +**/ +BOOLEAN +PmcIsLanDeepSxWakeEnabled ( + VOID + ) +{ + // + // Get wake info from PWRMBASE + DSX_CFG + // + return ((MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_DSX_CFG) & (UINT32) B_PMC_PWRM_DSX_CFG_LAN_WAKE_EN) != 0); +} + +/** + This function checks if eSPI SMI Lock is set + + @retval eSPI SMI Lock state +**/ +BOOLEAN +PmcIsEspiSmiLockSet ( + VOID + ) +{ + return ((MmioRead32 ((UINTN) (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A)) & B_PMC_PWRM_GEN_PMCON_A_ESPI_SMI_LOCK) != 0); +} + +/** + This function sets SW SMI Rate. + + @param[in] SwSmiRate Refer to PMC_SWSMI_RATE for possible values +**/ +VOID +PmcSetSwSmiRate ( + IN PMC_SWSMI_RATE SwSmiRate + ) +{ + UINT32 PchPwrmBase; + STATIC UINT8 SwSmiRateRegVal[4] = { + V_PMC_PWRM_GEN_PMCON_A_SWSMI_RTSL_1_5MS, + V_PMC_PWRM_GEN_PMCON_A_SWSMI_RTSL_16MS, + V_PMC_PWRM_GEN_PMCON_A_SWSMI_RTSL_32MS, + V_PMC_PWRM_GEN_PMCON_A_SWSMI_RTSL_64MS + }; + + ASSERT (SwSmiRate <= PmcSwSmiRate64ms); + + PchPwrmBase = PmcGetPwrmBase (); + + // + // SWSMI_RATE_SEL BIT (PWRMBASE offset 1020h[7:6]) bits are in RTC well + // + MmioAndThenOr8 ( + PchPwrmBase + R_PMC_PWRM_GEN_PMCON_A, + (UINT8)~B_PMC_PWRM_GEN_PMCON_A_SWSMI_RTSL, + SwSmiRateRegVal[SwSmiRate] + ); +} + +/** + This function sets Periodic SMI Rate. + + @param[in] PeriodicSmiRate Refer to PMC_PERIODIC_SMI_RATE for possible values +**/ +VOID +PmcSetPeriodicSmiRate ( + IN PMC_PERIODIC_SMI_RATE PeriodicSmiRate + ) +{ + UINT32 PchPwrmBase; + STATIC UINT8 PeriodicSmiRateRegVal[4] = { + V_PMC_PWRM_GEN_PMCON_A_PER_SMI_8S, + V_PMC_PWRM_GEN_PMCON_A_PER_SMI_16S, + V_PMC_PWRM_GEN_PMCON_A_PER_SMI_32S, + V_PMC_PWRM_GEN_PMCON_A_PER_SMI_64S + }; + + ASSERT (PeriodicSmiRate <= PmcPeriodicSmiRate64s); + + PchPwrmBase = PmcGetPwrmBase (); + + MmioAndThenOr8 ( + PchPwrmBase + R_PMC_PWRM_GEN_PMCON_A, + (UINT8)~B_PMC_PWRM_GEN_PMCON_A_PER_SMI_SEL, + PeriodicSmiRateRegVal[PeriodicSmiRate] + ); +} + +/** + This function reads Power Button Level + + @retval State of PWRBTN# signal (0: Low, 1: High) +**/ +UINT8 +PmcGetPwrBtnLevel ( + VOID + ) +{ + if (MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_B) & B_PMC_PWRM_GEN_PMCON_B_PWRBTN_LVL) { + return 1; + } else { + return 0; + } +} + +/** + This function gets Group to GPE0 configuration + + @param[out] GpeDw0Value GPIO Group to GPE_DW0 assignment + @param[out] GpeDw1Value GPIO Group to GPE_DW1 assignment + @param[out] GpeDw2Value GPIO Group to GPE_DW2 assignment +**/ +VOID +PmcGetGpioGpe ( + OUT UINT32 *GpeDw0Value, + OUT UINT32 *GpeDw1Value, + OUT UINT32 *GpeDw2Value + ) +{ + UINT32 Data32; + + Data32 = MmioRead32 ((UINTN) (PmcGetPwrmBase () + R_PMC_PWRM_GPIO_CFG)); + + *GpeDw0Value = ((Data32 & B_PMC_PWRM_GPIO_CFG_GPE0_DW0) >> N_PMC_PWRM_GPIO_CFG_GPE0_DW0); + *GpeDw1Value = ((Data32 & B_PMC_PWRM_GPIO_CFG_GPE0_DW1) >> N_PMC_PWRM_GPIO_CFG_GPE0_DW1); + *GpeDw2Value = ((Data32 & B_PMC_PWRM_GPIO_CFG_GPE0_DW2) >> N_PMC_PWRM_GPIO_CFG_GPE0_DW2); +} diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PmcPrivateLibWithS3.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PmcPrivateLibWithS3.c new file mode 100644 index 0000000000..02acd0d688 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PmcPrivateLibWithS3.c @@ -0,0 +1,122 @@ +/** @file + PCH private PMC Library. + All function in this library is available for PEI, DXE, and SMM, + But do not support UEFI RUNTIME environment call. + + Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <Base.h> +#include <Uefi/UefiBaseType.h> +#include <Library/IoLib.h> +#include <Library/DebugLib.h> +#include <Library/BaseLib.h> +#include <Library/PchCycleDecodingLib.h> +#include <Library/S3BootScriptLib.h> +#include <Library/PmcLib.h> +#include <Library/PmcPrivateLib.h> + +/** + This S3 BootScript only function disables triggering Global Reset of both + the Host and the ME partitions after CF9h write of 6h or Eh. +**/ +VOID +PmcDisableCf9GlobalResetInS3BootScript ( + VOID + ) +{ + UINT32 Data; + + UINT32 PchPwrmBase; + PchPwrmBase = PmcGetPwrmBase (); + + Data = MmioRead32 (PchPwrmBase + R_PMC_PWRM_ETR3); + + Data &= (UINT32) ~B_PMC_PWRM_ETR3_CF9GR; + + S3BootScriptSaveMemWrite ( + S3BootScriptWidthUint32, + (UINTN) PchPwrmBase + + R_PMC_PWRM_ETR3, + 1, + &Data + ); +} + +/** + This S3 BootScript only function disables triggering Global Reset of both + the Host and the ME partitions after CF9h write of 6h or Eh. + Global Reset configuration is locked after programming +**/ +VOID +PmcDisableCf9GlobalResetWithLockInS3BootScript ( + VOID + ) +{ + UINT32 Data; + + UINT32 PchPwrmBase; + PchPwrmBase = PmcGetPwrmBase (); + + Data = MmioRead32 (PchPwrmBase + R_PMC_PWRM_ETR3); + + Data &= (UINT32) ~B_PMC_PWRM_ETR3_CF9GR; + Data |= (UINT32) B_PMC_PWRM_ETR3_CF9LOCK; + + S3BootScriptSaveMemWrite ( + S3BootScriptWidthUint32, + (UINTN) PchPwrmBase + + R_PMC_PWRM_ETR3, + 1, + &Data + ); +} + +/** + This function sets SMI Lock with S3 Boot Script programming +**/ +VOID +PmcLockSmiWithS3BootScript ( + VOID + ) +{ + UINT32 PchPwrmBase; + + PchPwrmBase = PmcGetPwrmBase (); + + MmioOr8 ((UINTN) (PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B), B_PMC_PWRM_GEN_PMCON_B_SMI_LOCK); + + S3BootScriptSaveMemWrite ( + S3BootScriptWidthUint8, + (UINTN) (PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B), + 1, + (VOID *) (UINTN) (PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B) + ); +} + +/** + This function sets eSPI SMI Lock + @attention This function must be called after eSPI SMI generation has been enabled. + This setting is required in all boot modes and before EndOfDxe. + If set value will be restored upon S3 resume by bootscript. +**/ +VOID +PmcLockEspiSmiWithS3BootScript ( + VOID + ) +{ + UINT8 Data8Or; + UINT8 Data8And; + + Data8Or = (UINT8) (B_PMC_PWRM_GEN_PMCON_A_ESPI_SMI_LOCK >> 8); + Data8And = (UINT8)~((B_PMC_PWRM_GEN_PMCON_A_PWR_FLR | B_PMC_PWRM_GEN_PMCON_A_HOST_RST_STS) >> 8); + + MmioAndThenOr8 (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A + 1, Data8And, Data8Or); + S3BootScriptSaveMemReadWrite ( + S3BootScriptWidthUint8, + PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A + 1, + &Data8Or, + &Data8And + ); +} -- 2.24.0.windows.2 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#70974): https://edk2.groups.io/g/devel/message/70974 Mute This Topic: https://groups.io/mt/80274138/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-