REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171
Adds the following files: * IpBlock/SerialIo/IncludePrivate * IpBlock/SerialIo/Library * IpBlock/SerialIo/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/SerialIo/IncludePrivate/Library/SerialIoPrivateLib.h | 377 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/IncludePrivate/Register/SerialIoRegsVer2.h | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/Library/PeiDxeSmmSerialIoAccessLib/PeiDxeSmmSerialIoAccessLib.inf | 35 +++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/Library/PeiDxeSmmSerialIoAccessLib/SerialIoAccessLib.c | 266 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/PeiDxeSmmSerialIoPrivateLibVer2.inf | 34 ++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLib.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibI2c.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibI2cVer2.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibInternal.h | 20 ++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibSpi.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibSpiVer2.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibUart.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibUartVer2.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 13 files changed, 1610 insertions(+) diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/IncludePrivate/Library/SerialIoPrivateLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/IncludePrivate/Library/SerialIoPrivateLib.h new file mode 100644 index 0000000000..47057cd2ef --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/IncludePrivate/Library/SerialIoPrivateLib.h @@ -0,0 +1,377 @@ +/** @file + Header file for Serial IO Private Lib implementation. + + Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#ifndef _SERIAL_IO_PRIVATE_LIB_H_ +#define _SERIAL_IO_PRIVATE_LIB_H_ + +#include <SerialIoDevices.h> +#include <Library/SerialIoAccessLib.h> + +/** + Serial Io Pci Device State structure. + Used to preserve current information about the device when it is configured in Pci mode prior to Pch Initialization. +**/ +typedef struct { + UINT64 PciCfgBar0; ///< Pci Config Space Base Address Register + UINT8 PciCfgCommand; ///< Pci Config Space Command Register + UINT8 PciCfgPmeCtrlSts; ///< Pci Config Space Pme Control Status + UINT8 PprReset; ///< MMIO Proprietary Reset Register +} SERIAL_IO_PCI_DEVICE_STATE; + +/** + Checks if higher functions are enabled. + Used for Function 0 Serial Io Device disabling + + @param[in] DeviceNum Device Number + + @retval TRUE At least one higher function device is enabled + FALSE Higher functions are disabled +**/ +BOOLEAN +SerialIoHigherFunctionsEnabled ( + IN UINT8 DeviceNum + ); + +/** + Places SerialIo device in D3 + + @param[in] PciCfgBase Pci Config Offset + +**/ +VOID +SerialIoSetD3 ( + IN UINT64 PciCfgBase + ); + +/** + Places SerialIo device in D0 + + @param[in] PciCfgBase Pci Config Offset + +**/ +VOID +SerialIoSetD0 ( + IN UINT64 PciCfgBase + ); + +/** + Allows Memory Access + + @param[in] PciCfgBase Pci Config Offset + @param[in] Hidden Mode that determines access type + +**/ +VOID +SerialIoEnableMse ( + IN UINT64 PciCfgBase, + IN BOOLEAN Hidden + ); + +/** + Disable SerialIo memory access + + @param[in] PciCfgBase Pci Config Offset + +**/ +VOID +SerialIoDisableMse ( + IN UINT64 PciCfgBase + ); + +/** + Disable SerialIo memory encoding + Designated for Pci modes + + @param[in] PciCfgBase Pci Config Offset + @param[in] RemoveTempBar Remove temporary mem base address or not + +**/ +VOID +SerialIoMmioDisable ( + IN UINT64 PciCfgBase, + IN BOOLEAN RemoveBar + ); + +/** + Gets Fixed Base Address used for BAR0 + + @param[in] SpiNumber Serial IO device SPI number + + @retval Config control offset +**/ +UINT32 +GetSerialIoSpiFixedMmioAddress ( + IN UINT8 SpiNumber + ); + +/** + Gets Fixed Address used for Pci Config Space manipulation + + @param[in] SpiNumber Serial IO device SPI number + + @retval Pci Config Address +**/ +UINT32 +GetSerialIoSpiFixedPciCfgAddress ( + IN UINT8 SpiNumber + ); + +/** + Gets Spi Device Id + + @param[in] SpiNumber Serial IO device SPI number + + @retval Device Id +**/ +UINT16 +GetSerialIoSpiDeviceId ( + IN UINT8 SpiNumber + ); + +/** + Checks if SPI is Hidden, and it's Pci Config space available + + @param[in] SpiNumber Selects Serial IO SPI device + + @retval TRUE SPI is in hidden mode + @retval FALSE SPI is not in hidden mode +**/ +BOOLEAN +IsSerialIoSpiHidden ( + IN UINT8 SpiNumber + ); + +/** + Configures Serial IO Controller before control is passd to the OS + + @param[in] SpiNumber SPI Number + @param[in] SpiDeviceConfig SerialIo SPI Config + +**/ +VOID +SerialIoSpiBootHandler ( + IN UINT8 SpiNumber, + IN SERIAL_IO_SPI_CONFIG *SpiDeviceConfig + ); + +/** + Sets Pme Control Status and Command register values required for S3 Boot Script + + @param[in] SpiNumber SPI Number + @param[in] SpiDeviceConfig SerialIo SPI Config + @param[in/out] S3PciCfgBase S3 Boot Script Pci Config Base + @param[in/out] Command Pci Command register data to save + @param[in/out] Pme Pci Pme Control register data to save + +**/ +VOID +SerialIoSpiS3Handler ( + IN UINT8 SpiNumber, + IN SERIAL_IO_SPI_CONFIG *SpiDeviceConfig, + IN OUT UINT64 *S3PciCfgBase, + IN OUT UINT32 *Command, + IN OUT UINT32 *Pme + ); + +/** + Gets Pci Config control offset + + @param[in] UartNumber Serial IO device UART number + + @retval Config control offset +**/ +UINT16 +GetSerialIoUartConfigControlOffset ( + IN UINT8 UartNumber + ); + +/** + Gets Fixed Base Address used for BAR0 + + @param[in] UartNumber Serial IO device UART number + + @retval Config control offset +**/ +UINT32 +GetSerialIoUartFixedMmioAddress ( + IN UINT8 UartNumber + ); + +/** + Gets Fixed Address used for Pci Config Space manipulation + + @param[in] UartNumber Serial IO device UART number + + @retval Pci Config Address +**/ +UINT32 +GetSerialIoUartFixedPciCfgAddress ( + IN UINT8 UartNumber + ); + +/** + Returns UART S3 boot script PCI address + + @param[in] UartNumber UART Number + + @retval UART S3 boot script PCI address +**/ +UINT64 +GetSerialIoUartS3PciBase ( + IN UINT8 UartNumber + ); + +/** + Returns SPI S3 boot script PCI address + + @param[in] UartNumber UART Number + + @retval SPI S3 boot script PCI address +**/ +UINT64 +GetSerialIoSpiS3PciBase ( + IN UINT8 SpiNumber + ); + +/** + Returns I2C S3 boot script PCI address + + @param[in] I2cNumber I2C Number + + @retval I2C S3 boot script PCI address +**/ +UINT64 +GetSerialIoI2cS3PciBase ( + IN UINT8 I2cNumber + ); + +/** + Gets Uarts Device Id + + @param[in] UartNumbe Serial IO device UART number + + @retval Device Id +**/ +UINT16 +GetSerialIoUartDeviceId ( + IN UINT8 UartNumber + ); + +/** + Checks if UART is Hidden, and it's Pci Config space available + + @param[in] UartNumber Selects Serial IO UART device + + @retval TRUE UART is in hidden mode + @retval FALSE UART is not in hidden mode +**/ +BOOLEAN +IsSerialIoUartHidden ( + IN UINT8 UartNumber + ); + +/** + Configures Serial IO Controller before control is passd to the OS + + @param[in] UartNumber UART Number + @param[in] UartDeviceConfig SerialIo UART Config + +**/ +VOID +SerialIoUartBootHandler ( + IN UINT8 UartNumber, + IN SERIAL_IO_UART_CONFIG *UartDeviceConfig + ); + +/** + Sets Pme Control Status and Command register values required for S3 Boot Script + + @param[in] UartNumber UART Number + @param[in] UartDeviceConfig SerialIo UART Config + @param[in/out] S3PciCfgBase S3 Boot Script Pci Config Base + @param[in/out] Command Pci Command register data to save + @param[in/out] Pme Pci Pme Control register data to save + +**/ +VOID +SerialIoUartS3Handler ( + IN UINT8 UartNumber, + IN SERIAL_IO_UART_CONFIG *UartDeviceConfig, + IN OUT UINT64 *S3PciCfgBase, + IN OUT UINT32 *Command, + IN OUT UINT32 *Pme + ); + +/** + Gets Fixed Address used for Pci Config Space manipulation + + @param[in] I2cNumber Serial IO device I2C number + + @retval Pci Config Address +**/ +UINT32 +GetSerialIoI2cFixedPciCfgAddress ( + IN UINT8 I2cNumber + ); + +/** + Gets I2C Device Id + + @param[in] I2cNumber Serial IO device I2C number + + @retval Device Id +**/ +UINT16 +GetSerialIoI2cDeviceId ( + IN UINT8 I2cNumber + ); + +/** + Checks if I2C is Hidden, and it's Pci Config space available + + @param[in] 2cNumber Selects Serial IO I2C device + + @retval TRUE I2C is in hidden mode + @retval FALSE I2C is not in hidden mode +**/ +BOOLEAN +IsSerialIoI2cHidden ( + IN UINT8 I2cNumber + ); + +/** + Configures Serial IO Controller before control is passd to the OS + + @param[in] I2cNumber I2C Number + @param[in] I2cDeviceConfig SerialIo I2C Config + +**/ +VOID +SerialIoI2cBootHandler ( + IN UINT8 I2cNumber, + IN SERIAL_IO_I2C_CONFIG *I2cDeviceConfig + ); + +/** + Sets Pme Control Status and Command register values required for S3 Boot Script + + @param[in] I2cNumber I2C Number + @param[in] I2cDeviceConfig SerialIo I2C Config + @param[in/out] S3PciCfgBase S3 Boot Script Pci Config Base + @param[in/out] Command Pci Command register data to save + @param[in/out] Pme Pci Pme Control register data to save + +**/ +VOID +SerialIoI2cS3Handler ( + IN UINT8 I2cNumber, + IN SERIAL_IO_I2C_CONFIG *I2cDeviceConfig, + IN OUT UINT64 *S3PciCfgBase, + IN OUT UINT32 *Command, + IN OUT UINT32 *Pme + ); + +#endif // _SERIAL_IO_PRIVATE_LIB_H_ diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/IncludePrivate/Register/SerialIoRegsVer2.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/IncludePrivate/Register/SerialIoRegsVer2.h new file mode 100644 index 0000000000..01840b14c9 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/IncludePrivate/Register/SerialIoRegsVer2.h @@ -0,0 +1,108 @@ +/** @file + Device IDs for Serial IO Controllers for TGL PCH + + 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 _SERIAL_IO_REGS_VER2_H_ +#define _SERIAL_IO_REGS_VER2_H_ +// +// Serial IO I2C0 Controller Registers +// +#define V_VER2_PCH_LP_SERIAL_IO_CFG_I2C0_DEVICE_ID 0xA0E8 + +// +// Serial IO I2C1 Controller Registers +// +#define V_VER2_PCH_LP_SERIAL_IO_CFG_I2C1_DEVICE_ID 0xA0E9 + +// +// Serial IO I2C2 Controller Registers +// +#define V_VER2_PCH_LP_SERIAL_IO_CFG_I2C2_DEVICE_ID 0xA0EA + +// +// Serial IO I2C3 Controller Registers +// +#define V_VER2_PCH_LP_SERIAL_IO_CFG_I2C3_DEVICE_ID 0xA0EB + +// +// Serial IO I2C4 Controller Registers +// +#define V_VER2_PCH_LP_SERIAL_IO_CFG_I2C4_DEVICE_ID 0xA0C5 + +// +// Serial IO I2C5 Controller Registers +// +#define V_VER2_PCH_LP_SERIAL_IO_CFG_I2C5_DEVICE_ID 0xA0C6 + +// +// Serial IO SPI0 Controller Registers +// +#define V_VER2_PCH_LP_SERIAL_IO_CFG_SPI0_DEVICE_ID 0xA0AA + +// +// Serial IO SPI1 Controller Registers +// +#define V_VER2_PCH_LP_SERIAL_IO_CFG_SPI1_DEVICE_ID 0xA0AB + +// +// Serial IO SPI2 Controller Registers +// +#define V_VER2_PCH_LP_SERIAL_IO_CFG_SPI2_DEVICE_ID 0xA0FB + +// +// Serial IO SPI3 Controller Registers +// +#define V_VER2_PCH_LP_SERIAL_IO_CFG_SPI3_DEVICE_ID 0xA0FD + +// +// Serial IO UART0 Controller Registers +// +#define V_VER2_PCH_LP_SERIAL_IO_CFG_UART0_DEVICE_ID 0xA0A8 + +// +// Serial IO UART1 Controller Registers +// +#define V_VER2_PCH_LP_SERIAL_IO_CFG_UART1_DEVICE_ID 0xA0A9 + +// +// Serial IO UART2 Controller Registers +// +#define V_VER2_PCH_LP_SERIAL_IO_CFG_UART2_DEVICE_ID 0xA0C7 + +// +// Serial IO UART3 Controller Registers +// +#define V_VER2_PCH_LP_SERIAL_IO_CFG_UART3_DEVICE_ID 0xA0DA + +#endif //_SERIAL_IO_REGS_VER2_H_ diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/Library/PeiDxeSmmSerialIoAccessLib/PeiDxeSmmSerialIoAccessLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/Library/PeiDxeSmmSerialIoAccessLib/PeiDxeSmmSerialIoAccessLib.inf new file mode 100644 index 0000000000..9178840ca8 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/Library/PeiDxeSmmSerialIoAccessLib/PeiDxeSmmSerialIoAccessLib.inf @@ -0,0 +1,35 @@ +## @file +# Component description file for PEI/DXE/SMM Serial Io Access 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 = PeiDxeSmmSerialIoAccessLib + FILE_GUID = F1A20692-26CA-4CA4-A775-695BBD6D3EC7 + VERSION_STRING = 1.0 + MODULE_TYPE = BASE + LIBRARY_CLASS = SerialIoAccessLib + +[LibraryClasses] + BaseLib + IoLib + DebugLib + PcdLib + PciSegmentLib + PchPcrLib + SerialIoPrivateLib + +[Packages] + MdePkg/MdePkg.dec + TigerlakeSiliconPkg/SiPkg.dec + +[Sources] + SerialIoAccessLib.c diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/Library/PeiDxeSmmSerialIoAccessLib/SerialIoAccessLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/Library/PeiDxeSmmSerialIoAccessLib/SerialIoAccessLib.c new file mode 100644 index 0000000000..2b3a3dca5a --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/Library/PeiDxeSmmSerialIoAccessLib/SerialIoAccessLib.c @@ -0,0 +1,266 @@ +/** @file + Serial Io Common Lib implementation. + 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 <Include/PcieRegs.h> +#include <IndustryStandard/Pci30.h> +#include <Register/PchRegs.h> +#include <Library/IoLib.h> +#include <Library/BaseLib.h> +#include <Library/SerialIoAccessLib.h> +#include <Library/SerialIoPrivateLib.h> +#include <Library/PciSegmentLib.h> +#include <Library/PchInfoLib.h> +#include <Library/S3BootScriptLib.h> +#include <Library/DebugLib.h> +#include <PchLimits.h> +#include <PchReservedResources.h> +#include <Library/PchPciBdfLib.h> + +/** + Returns BAR0 + + @param[in] PciCfgBase Pci Config Base + + @retval 64bit MMIO BAR Address +**/ +UINT64 +GetSerialIoBar ( + IN UINT64 PciCfgBase + ) +{ + if (PciCfgBase < PCH_SERIAL_IO_BASE_ADDRESS) { + return (UINT64) ((PciSegmentRead32 ((UINTN) (PciCfgBase + PCI_BASE_ADDRESSREG_OFFSET)) & 0xFFFFF000) + LShiftU64 (PciSegmentRead32 ((UINTN) (PciCfgBase + PCI_BASE_ADDRESSREG_OFFSET + 4)), 32)); + } + return (UINT64) ((MmioRead32 ((UINTN) (PciCfgBase + PCI_BASE_ADDRESSREG_OFFSET)) & 0xFFFFF000) + LShiftU64 (MmioRead32 ((UINTN) (PciCfgBase + PCI_BASE_ADDRESSREG_OFFSET + 4)), 32)); +} + +/** + Returns I2C Pci Config Space + + @param[in] I2cNumber I2C Number + + @retval I2C Pci Config Space Address +**/ +UINT64 +GetSerialIoI2cPciCfg ( + IN UINT8 I2cNumber + ) +{ + if (IsSerialIoI2cHidden (I2cNumber)) { + return (UINTN) GetSerialIoI2cFixedPciCfgAddress (I2cNumber); + } + return SerialIoI2cPciCfgBase (I2cNumber); +} + +/** + Returns SPI Pci Config Space + + @param[in] SpiNumber SPI Number + + @retval SPI Pci Config Space Address +**/ +UINT64 +GetSerialIoSpiPciCfg ( + IN UINT8 SpiNumber + ) +{ + if (IsSerialIoSpiHidden (SpiNumber)) { + return (UINTN) GetSerialIoSpiFixedPciCfgAddress (SpiNumber); + } + return SerialIoSpiPciCfgBase (SpiNumber); +} + +/** + Returns UART Pci Config Space + + @param[in] UartNumber UART Number + + @retval UART Pci Config Space Address +**/ +UINT64 +GetSerialIoUartPciCfg ( + IN UINT8 UartNumber + ) +{ + if (IsSerialIoUartHidden (UartNumber)) { + return GetSerialIoUartFixedPciCfgAddress (UartNumber); + } + return SerialIoUartPciCfgBase (UartNumber); +} + +/** + Returns SPI S3 boot script PCI address + + @param[in] UartNumber UART Number + + @retval SPI S3 boot script PCI address +**/ +UINT64 +GetSerialIoSpiS3PciBase ( + IN UINT8 SpiNumber + ) +{ + if (IsSerialIoSpiHidden (SpiNumber)) { + // + // It's not expected to return Spi S3 Boot Script PCI address for non PCI mode. + // + ASSERT (TRUE); + } + return S3_BOOT_SCRIPT_LIB_PCI_ADDRESS ( + DEFAULT_PCI_BUS_NUMBER_PCH, + SerialIoSpiDevNumber (SpiNumber), + SerialIoSpiFuncNumber (SpiNumber), + 0 + ); +} + +/** + Returns UART S3 boot script PCI address + + @param[in] UartNumber UART Number + + @retval UART S3 boot script PCI address +**/ +UINT64 +GetSerialIoUartS3PciBase ( + IN UINT8 UartNumber + ) +{ + if (IsSerialIoUartHidden (UartNumber)) { + // + // It's not expected to return Uart S3 Boot Script PCI address for non PCI mode. + // + ASSERT (TRUE); + } + return S3_BOOT_SCRIPT_LIB_PCI_ADDRESS ( + DEFAULT_PCI_BUS_NUMBER_PCH, + SerialIoUartDevNumber (UartNumber), + SerialIoUartFuncNumber (UartNumber), + 0 + ); +} + +/** + Returns I2C S3 boot script PCI address + + @param[in] I2cNumber I2C Number + + @retval I2C S3 boot script PCI address +**/ +UINT64 +GetSerialIoI2cS3PciBase ( + IN UINT8 I2cNumber + ) +{ + if (IsSerialIoI2cHidden (I2cNumber)) { + // + // It's not expected to return I2c S3 Boot Script PCI address for non PCI mode. + // + ASSERT (TRUE); + } + return S3_BOOT_SCRIPT_LIB_PCI_ADDRESS ( + DEFAULT_PCI_BUS_NUMBER_PCH, + SerialIoI2cDevNumber (I2cNumber), + SerialIoI2cFuncNumber (I2cNumber), + 0 + ); +} + +/** + Checks if Device with given PciDeviceId is one of SerialIo I2C controllers + If yes, its number is returned through I2cIndex parameter, otherwise I2cIndex is not updated + + @param[in] PciDevId Device ID + @param[out] I2cNumber Number of SerialIo I2C controller + + @retval TRUE yes it is a SerialIo I2C controller + @retval FALSE no it isn't a SerialIo I2C controller +**/ +BOOLEAN +IsSerialIoI2cDeviceId ( + IN UINT16 PciDevId, + OUT UINT8 *I2cNumber + ) +{ + UINT8 Index; + + for (Index = 0; Index < GetPchMaxSerialIoI2cControllersNum (); Index++) { + if (PciDevId == GetSerialIoI2cDeviceId (Index)) { + *I2cNumber = Index; + return TRUE; + } + } + return FALSE; +} + +/** + Checks if I2c is Function 0 Enabled + + @param[in] I2cIndex Number of the SerialIo I2C controller + + @retval TRUE Enabled + @retval FALSE Disabled +**/ +BOOLEAN +IsSerialIoI2cFunction0Enabled ( + IN UINT8 I2cIndex + ) +{ + if (SerialIoI2cFuncNumber (I2cIndex) == 0) { + if (SerialIoHigherFunctionsEnabled (SerialIoI2cDevNumber (I2cIndex))) { + return TRUE; + } + } + return FALSE; +} + +/** + Checks if Uart is Function 0 Enabled + + @param[in] UartIndex Number of the SerialIo Uart controller + + @retval TRUE Enabled + @retval FALSE Disabled +**/ +BOOLEAN +IsSerialIoUartFunction0Enabled ( + IN UINT8 UartIndex + ) +{ + if (SerialIoUartFuncNumber (UartIndex) == 0) { + if (SerialIoHigherFunctionsEnabled (SerialIoUartDevNumber (UartIndex))) { + return TRUE; + } + } + return FALSE; +} + +/** + Checks if Spi is Function 0 Enabled + + @param[in] SpiIndex Number of the SerialIo Spi controller + + @retval TRUE Enabled + @retval FALSE Disabled +**/ +BOOLEAN +IsSerialIoSpiFunction0Enabled ( + IN UINT8 SpiIndex + ) +{ + if (SerialIoSpiFuncNumber (SpiIndex) == 0) { + if (SerialIoHigherFunctionsEnabled (SerialIoSpiDevNumber (SpiIndex))) { + return TRUE; + } + } + return FALSE; +} + diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/PeiDxeSmmSerialIoPrivateLibVer2.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/PeiDxeSmmSerialIoPrivateLibVer2.inf new file mode 100644 index 0000000000..8981be2496 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/PeiDxeSmmSerialIoPrivateLibVer2.inf @@ -0,0 +1,34 @@ +## @file +# Serial Io Private Lib Ver 2 +# +# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010017 + BASE_NAME = PeiDxeSmmSerialIoLibVer2 + FILE_GUID = 9D9F99CD-C072-48C2-BF78-ABA3D664C0FA + VERSION_STRING = 1.0 + MODULE_TYPE = BASE + LIBRARY_CLASS = SerialIoPrivateLib + +[LibraryClasses] + BaseLib + IoLib + PciSegmentLib + SerialIoAccessLib + +[Packages] + MdePkg/MdePkg.dec + TigerlakeSiliconPkg/SiPkg.dec + +[Sources] + SerialIoPrivateLib.c + SerialIoPrivateLibI2c.c + SerialIoPrivateLibI2cVer2.c + SerialIoPrivateLibSpi.c + SerialIoPrivateLibSpiVer2.c + SerialIoPrivateLibUart.c + SerialIoPrivateLibUartVer2.c diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLib.c new file mode 100644 index 0000000000..9b84c2dda6 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLib.c @@ -0,0 +1,156 @@ +/** @file + Serial IO Private Lib implementation. + 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/BaseLib.h> +#include <Library/SerialIoAccessLib.h> +#include <Library/SerialIoPrivateLib.h> +#include <Library/PciSegmentLib.h> +#include <Register/PchRegs.h> +#include <Register/SerialIoRegs.h> +#include <Include/PcieRegs.h> +#include <IndustryStandard/Pci30.h> +#include <PchReservedResources.h> + +/** + Checks if higher functions are enabled. + Used for Function 0 Serial Io Device disabling + + @param[in] DeviceNum Device Number + + @retval TRUE At least one higher function device is enabled + FALSE Higher functions are disabled +**/ +BOOLEAN +SerialIoHigherFunctionsEnabled ( + IN UINT8 DeviceNum + ) +{ + UINT8 FuncNum; + // + // Check all other func devs(1 to 7) status except func 0. + // + for (FuncNum = 1; FuncNum <= PCI_MAX_FUNC; FuncNum++) { + if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (DEFAULT_PCI_SEGMENT_NUMBER_PCH, + DEFAULT_PCI_BUS_NUMBER_PCH, + DeviceNum, + FuncNum, + PCI_DEVICE_ID_OFFSET) + ) != 0xFFFF) { + return TRUE; + } + } + return FALSE; +} + +/** + Places SerialIo device in D3 + + @param[in] PciCfgBase Pci Config Offset + +**/ +VOID +SerialIoSetD3 ( + IN UINT64 PciCfgBase + ) +{ + if (PciCfgBase < PCH_SERIAL_IO_BASE_ADDRESS) { + PciSegmentOr32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, BIT1 | BIT0); + } else { + MmioOr8 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, BIT1 | BIT0); + // + // Reading back value after write to ensure bridge observes the BAR1 write access + // + MmioRead8 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS); + } +} + +/** + Places SerialIo device in D0 + + @param[in] PciCfgBase Pci Config Offset + +**/ +VOID +SerialIoSetD0 ( + IN UINT64 PciCfgBase + ) +{ + if (PciCfgBase < PCH_SERIAL_IO_BASE_ADDRESS) { + PciSegmentAnd32 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, (UINT32) ~(BIT1 | BIT0)); + } else { + MmioAnd32 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, (UINT32) ~(BIT1 | BIT0)); + // + // Reading back value after write to ensure bridge observes the BAR1 write access + // + MmioRead32 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS); + } +} + +/** + Allows memory access + + @param[in] PciCfgBase Pci Config Offset + @param[in] Hidden Mode that determines access type + +**/ +VOID +SerialIoEnableMse ( + IN UINT64 PciCfgBase, + IN BOOLEAN Hidden + ) +{ + if (Hidden) { + MmioOr16 ((UINTN) PciCfgBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE); + // + // Reading back value after write to ensure bridge observes the BAR1 write access + // + MmioRead16 ((UINTN) PciCfgBase + PCI_COMMAND_OFFSET); + } else { + PciSegmentOr16 ((UINTN) PciCfgBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE); + } +} + +/** + Disable SerialIo memory access + + @param[in] PciCfgBase Pci Config Offset + +**/ +VOID +SerialIoDisableMse ( + IN UINT64 PciCfgBase + ) +{ + PciSegmentAnd16 ((UINTN) PciCfgBase + PCI_COMMAND_OFFSET, (UINT16) ~EFI_PCI_COMMAND_MEMORY_SPACE); +} + +/** + Disable SerialIo memory encoding + Designated for Pci modes + + @param[in] PciCfgBase Pci Config Offset + @param[in] RemoveTempBar Remove temporary mem base address or not + +**/ +VOID +SerialIoMmioDisable ( + IN UINT64 PciCfgBase, + IN BOOLEAN RemoveBar + ) +{ + SerialIoDisableMse (PciCfgBase); + + if (RemoveBar == TRUE) { + PciSegmentWrite32 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_BAR0_LOW, 0x0); + PciSegmentWrite32 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_BAR0_HIGH, 0x0); + } +} diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibI2c.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibI2c.c new file mode 100644 index 0000000000..7601081cfa --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibI2c.c @@ -0,0 +1,122 @@ +/** @file + Common Serial IO Private Lib implementation - I2C part + 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/BaseLib.h> +#include <Library/PchInfoLib.h> +#include <Library/PciSegmentLib.h> +#include <Library/SerialIoAccessLib.h> +#include <Library/SerialIoPrivateLib.h> +#include <IndustryStandard/Pci30.h> +#include <Register/PchRegs.h> +#include <Register/SerialIoRegs.h> +#include <SerialIoPrivateLibInternal.h> +#include <PchLimits.h> +#include <Library/PchPciBdfLib.h> + +/** + Checks if I2C is Hidden, and it's Pci Config space available + + @param[in] I2cNumber Selects Serial IO I2C device + + @retval TRUE I2C is in hidden mode + @retval FALSE I2C is not in hidden mode +**/ +BOOLEAN +IsSerialIoI2cHidden ( + IN UINT8 I2cNumber + ) +{ + if (MmioRead16 (GetSerialIoI2cFixedPciCfgAddress (I2cNumber) + PCI_DEVICE_ID_OFFSET) == GetSerialIoI2cDeviceId (I2cNumber)) { + return TRUE; + } + return FALSE; +} + +/** + Configures Serial IO Controller before control is passd to the OS + + @param[in] I2cNumber I2C Number + @param[in] I2cDeviceConfig SerialIo I2C Config + +**/ +VOID +SerialIoI2cBootHandler ( + IN UINT8 I2cNumber, + IN SERIAL_IO_I2C_CONFIG *I2cDeviceConfig + ) +{ + UINT64 PciCfgBase; + BOOLEAN TurnOff; + + TurnOff = FALSE; + + if (I2cDeviceConfig->Mode == SerialIoI2cPci) { + TurnOff = TRUE; + } + + if ((I2cDeviceConfig->Mode == SerialIoI2cDisabled) && (SerialIoI2cFuncNumber (I2cNumber) == 0x0)) { + if (SerialIoHigherFunctionsEnabled (SerialIoI2cDevNumber (I2cNumber))) { + TurnOff = TRUE; + } + } + + if (TurnOff) { + PciCfgBase = GetSerialIoI2cPciCfg (I2cNumber); + SerialIoSetD3 (PciCfgBase); + SerialIoMmioDisable (PciCfgBase, TRUE); + } +} + +/** + Sets Pme Control Status and Command register values required for S3 Boot Script + + @param[in] I2cNumber I2C Number + @param[in] I2cDeviceConfig SerialIo I2C Config + @param[in/out] S3PciCfgBase S3 Boot Script Pci Config Base + @param[in/out] Command Pci Command register data to save + @param[in/out] Pme Pci Pme Control register data to save + +**/ +VOID +SerialIoI2cS3Handler ( + IN UINT8 I2cNumber, + IN SERIAL_IO_I2C_CONFIG *I2cDeviceConfig, + IN OUT UINT64 *S3PciCfgBase, + IN OUT UINT32 *Command, + IN OUT UINT32 *Pme + ) +{ + BOOLEAN TurnOff; + UINT64 PciCfgBase; + + *S3PciCfgBase = 0; + TurnOff = FALSE; + + if (I2cDeviceConfig->Mode == SerialIoI2cPci) { + TurnOff = TRUE; + } + + if ((I2cDeviceConfig->Mode == SerialIoI2cDisabled) && (SerialIoI2cFuncNumber (I2cNumber) == 0x0)) { + if (SerialIoHigherFunctionsEnabled (SerialIoI2cDevNumber (I2cNumber))) { + TurnOff = TRUE; + } + } + + if (TurnOff) { + *S3PciCfgBase = GetSerialIoI2cS3PciBase (I2cNumber); + PciCfgBase = GetSerialIoI2cPciCfg (I2cNumber); + *Pme = PciSegmentRead32 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS); + *Pme = *Pme | BIT0 | BIT1; + *Command = PciSegmentRead32 ((UINTN) PciCfgBase + PCI_COMMAND_OFFSET); + *Command = *Command & (UINT32)~(EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER); + } +} diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibI2cVer2.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibI2cVer2.c new file mode 100644 index 0000000000..fd684ca2a9 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibI2cVer2.c @@ -0,0 +1,70 @@ +/** @file + Serial IO I2C Private Lib implementation TigerLake specific. + 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/BaseLib.h> +#include <Library/PchInfoLib.h> +#include <Register/SerialIoRegsVer2.h> +#include <IndustryStandard/Pci30.h> +#include <SerialIoPrivateLibInternal.h> +#include <PchReservedResources.h> +#include <PchLimits.h> + +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchLpSerialIoI2cDevId [] = { + V_VER2_PCH_LP_SERIAL_IO_CFG_I2C0_DEVICE_ID, + V_VER2_PCH_LP_SERIAL_IO_CFG_I2C1_DEVICE_ID, + V_VER2_PCH_LP_SERIAL_IO_CFG_I2C2_DEVICE_ID, + V_VER2_PCH_LP_SERIAL_IO_CFG_I2C3_DEVICE_ID, + V_VER2_PCH_LP_SERIAL_IO_CFG_I2C4_DEVICE_ID, + V_VER2_PCH_LP_SERIAL_IO_CFG_I2C5_DEVICE_ID +}; + +GLOBAL_REMOVE_IF_UNREFERENCED SERIAL_IO_CONTROLLER_DESCRIPTOR mSerialIoI2cFixedAddress [] = { + {PCH_SERIAL_IO_BASE_ADDRESS + 0x0000, PCH_SERIAL_IO_BASE_ADDRESS + 0x1000}, + {PCH_SERIAL_IO_BASE_ADDRESS + 0x2000, PCH_SERIAL_IO_BASE_ADDRESS + 0x3000}, + {PCH_SERIAL_IO_BASE_ADDRESS + 0x4000, PCH_SERIAL_IO_BASE_ADDRESS + 0x5000}, + {PCH_SERIAL_IO_BASE_ADDRESS + 0x6000, PCH_SERIAL_IO_BASE_ADDRESS + 0x7000}, + {PCH_SERIAL_IO_BASE_ADDRESS + 0x8000, PCH_SERIAL_IO_BASE_ADDRESS + 0x9000}, + {PCH_SERIAL_IO_BASE_ADDRESS + 0xA000, PCH_SERIAL_IO_BASE_ADDRESS + 0xB000}, + {PCH_SERIAL_IO_BASE_ADDRESS + 0xC000, PCH_SERIAL_IO_BASE_ADDRESS + 0xD000}, + {PCH_SERIAL_IO_BASE_ADDRESS + 0xE000, PCH_SERIAL_IO_BASE_ADDRESS + 0xF000} +}; + +/** + Gets Fixed Address used for Pci Config Space manipulation + + @param[in] I2cNumber Serial IO device I2C number + + @retval Pci Config Address +**/ +UINT32 +GetSerialIoI2cFixedPciCfgAddress ( + IN UINT8 I2cNumber + ) +{ + return mSerialIoI2cFixedAddress[I2cNumber].Bar1; +} + + +/** + Gets I2C Device Id + + @param[in] I2cNumber Serial IO device I2C number + + @retval Device Id +**/ +UINT16 +GetSerialIoI2cDeviceId ( + IN UINT8 I2cNumber + ) +{ + return mPchLpSerialIoI2cDevId[I2cNumber]; +} diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibInternal.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibInternal.h new file mode 100644 index 0000000000..b5e8aba9ac --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibInternal.h @@ -0,0 +1,20 @@ +/** @file + Header file for SerialIoPrivateLibInternal. + + Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#ifndef _SERIAL_IO_PRIVATE_LIB_INTERNAL_H_ +#define _SERIAL_IO_PRIVATE_LIB_INTERNAL_H_ + +typedef struct { + UINT32 Bar0; + UINT32 Bar1; +} SERIAL_IO_CONTROLLER_DESCRIPTOR; + +typedef struct { + UINT8 DevNum; + UINT8 FuncNum; +} SERIAL_IO_BDF_NUMBERS; + +#endif diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibSpi.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibSpi.c new file mode 100644 index 0000000000..a926941baf --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibSpi.c @@ -0,0 +1,122 @@ +/** @file + Common Serial IO Private Lib implementation - SPI part + 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/BaseLib.h> +#include <Library/PchInfoLib.h> +#include <Library/PciSegmentLib.h> +#include <Library/SerialIoAccessLib.h> +#include <Library/SerialIoPrivateLib.h> +#include <IndustryStandard/Pci30.h> +#include <Register/PchRegs.h> +#include <Register/SerialIoRegs.h> +#include <SerialIoPrivateLibInternal.h> +#include <PchLimits.h> +#include <Library/PchPciBdfLib.h> + +/** + Checks if SPI is Hidden, and it's Pci Config space available + + @param[in] SpiNumber Selects Serial IO SPI device + + @retval TRUE SPI is in hidden mode + @retval FALSE SPI is not in hidden mode +**/ +BOOLEAN +IsSerialIoSpiHidden ( + IN UINT8 SpiNumber + ) +{ + if (MmioRead16 (GetSerialIoSpiFixedPciCfgAddress (SpiNumber) + PCI_DEVICE_ID_OFFSET) == GetSerialIoSpiDeviceId (SpiNumber)) { + return TRUE; + } + return FALSE; +} + +/** + Configures Serial IO Controller before control is passd to the OS + + @param[in] SpiNumber SPI Number + @param[in] SpiDeviceConfig SerialIo SPI Config + +**/ +VOID +SerialIoSpiBootHandler ( + IN UINT8 SpiNumber, + IN SERIAL_IO_SPI_CONFIG *SpiDeviceConfig + ) +{ + UINT64 PciCfgBase; + BOOLEAN TurnOff; + + TurnOff = FALSE; + + if (SpiDeviceConfig->Mode == SerialIoSpiPci) { + TurnOff = TRUE; + } + + if ((SpiDeviceConfig->Mode == SerialIoSpiDisabled) && (SerialIoSpiFuncNumber (SpiNumber) == 0x0)) { + if (SerialIoHigherFunctionsEnabled (SerialIoSpiDevNumber (SpiNumber))) { + TurnOff = TRUE; + } + } + + if (TurnOff) { + PciCfgBase = GetSerialIoSpiPciCfg (SpiNumber); + SerialIoSetD3 (PciCfgBase); + SerialIoMmioDisable (PciCfgBase, TRUE); + } +} + +/** + Sets Pme Control Status and Command register values required for S3 Boot Script + + @param[in] SpiNumber SPI Number + @param[in] SpiDeviceConfig SerialIo SPI Config + @param[in/out] S3PciCfgBase S3 Boot Script Pci Config Base + @param[in/out] Command Pci Command register data to save + @param[in/out] Pme Pci Pme Control register data to save + +**/ +VOID +SerialIoSpiS3Handler ( + IN UINT8 SpiNumber, + IN SERIAL_IO_SPI_CONFIG *SpiDeviceConfig, + IN OUT UINT64 *S3PciCfgBase, + IN OUT UINT32 *Command, + IN OUT UINT32 *Pme + ) +{ + BOOLEAN TurnOff; + UINT64 PciCfgBase; + + *S3PciCfgBase = 0; + TurnOff = FALSE; + + if (SpiDeviceConfig->Mode == SerialIoSpiPci) { + TurnOff = TRUE; + } + + if ((SpiDeviceConfig->Mode == SerialIoSpiDisabled) && (SerialIoSpiFuncNumber (SpiNumber) == 0x0)) { + if (SerialIoHigherFunctionsEnabled (SerialIoSpiDevNumber (SpiNumber))) { + TurnOff = TRUE; + } + } + + if (TurnOff) { + *S3PciCfgBase = GetSerialIoSpiS3PciBase (SpiNumber); + PciCfgBase = GetSerialIoSpiPciCfg (SpiNumber); + *Pme = PciSegmentRead32 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS); + *Pme = *Pme | BIT0 | BIT1; + *Command = PciSegmentRead32 ((UINTN) PciCfgBase + PCI_COMMAND_OFFSET); + *Command = *Command & (UINT32)~(EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER); + } +} diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibSpiVer2.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibSpiVer2.c new file mode 100644 index 0000000000..abda359202 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibSpiVer2.c @@ -0,0 +1,82 @@ +/** @file + Serial IO Spi Private Lib implementation TigerLake specific. + 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/BaseLib.h> +#include <Library/PchInfoLib.h> +#include <Register/SerialIoRegsVer2.h> +#include <IndustryStandard/Pci30.h> +#include <SerialIoPrivateLibInternal.h> +#include <PchReservedResources.h> +#include <PchLimits.h> + +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchLpSerialIoSpiDevId [] = { + V_VER2_PCH_LP_SERIAL_IO_CFG_SPI0_DEVICE_ID, + V_VER2_PCH_LP_SERIAL_IO_CFG_SPI1_DEVICE_ID, + V_VER2_PCH_LP_SERIAL_IO_CFG_SPI2_DEVICE_ID, + V_VER2_PCH_LP_SERIAL_IO_CFG_SPI3_DEVICE_ID +}; + +GLOBAL_REMOVE_IF_UNREFERENCED SERIAL_IO_CONTROLLER_DESCRIPTOR mSerialIoSpiFixedAddress [] = { + {PCH_SERIAL_IO_BASE_ADDRESS + 0x10000, PCH_SERIAL_IO_BASE_ADDRESS + 0x11000}, + {PCH_SERIAL_IO_BASE_ADDRESS + 0x12000, PCH_SERIAL_IO_BASE_ADDRESS + 0x13000}, + {PCH_SERIAL_IO_BASE_ADDRESS + 0x14000, PCH_SERIAL_IO_BASE_ADDRESS + 0x15000}, + {PCH_SERIAL_IO_BASE_ADDRESS + 0x16000, PCH_SERIAL_IO_BASE_ADDRESS + 0x17000}, + {PCH_SERIAL_IO_BASE_ADDRESS + 0x18000, PCH_SERIAL_IO_BASE_ADDRESS + 0x19000}, + {PCH_SERIAL_IO_BASE_ADDRESS + 0x1A000, PCH_SERIAL_IO_BASE_ADDRESS + 0x1B000}, + {PCH_SERIAL_IO_BASE_ADDRESS + 0x1C000, PCH_SERIAL_IO_BASE_ADDRESS + 0x1D000} +}; + +/** + Gets Fixed Base Address used for BAR0 + + @param[in] SpiNumber Serial IO device SPI number + + @retval Config control offset +**/ +UINT32 +GetSerialIoSpiFixedMmioAddress ( + IN UINT8 SpiNumber + ) +{ + return mSerialIoSpiFixedAddress[SpiNumber].Bar0; +} + +/** + Gets Fixed Address used for Pci Config Space manipulation + + @param[in] SpiNumber Serial IO device SPI number + + @retval Pci Config Address +**/ +UINT32 +GetSerialIoSpiFixedPciCfgAddress ( + IN UINT8 SpiNumber + ) +{ + return mSerialIoSpiFixedAddress[SpiNumber].Bar1; +} + +/** + Gets Spi Device Id + + @param[in] SpiNumber Serial IO device SPI number + + @retval Device Id +**/ +UINT16 +GetSerialIoSpiDeviceId ( + IN UINT8 SpiNumber + ) +{ + return mPchLpSerialIoSpiDevId[SpiNumber]; +} + diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibUart.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibUart.c new file mode 100644 index 0000000000..0f7d6513ce --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibUart.c @@ -0,0 +1,136 @@ +/** @file + Serial IO Private Lib implementation - UART part + 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/BaseLib.h> +#include <Library/PchInfoLib.h> +#include <Library/PciSegmentLib.h> +#include <Library/SerialIoAccessLib.h> +#include <Library/SerialIoPrivateLib.h> +#include <IndustryStandard/Pci30.h> +#include <Register/PchRegs.h> +#include <Register/SerialIoRegs.h> +#include <SerialIoPrivateLibInternal.h> +#include <PchLimits.h> +#include <Library/PchPciBdfLib.h> + +/** + Checks if UART is Hidden, and it's Pci Config space available + + @param[in] UartNumber Selects Serial IO UART device + + @retval TRUE UART is in hidden mode + @retval FALSE UART is not in hidden mode +**/ +BOOLEAN +IsSerialIoUartHidden ( + IN UINT8 UartNumber + ) +{ + if (MmioRead16 (GetSerialIoUartFixedPciCfgAddress (UartNumber) + PCI_DEVICE_ID_OFFSET) == GetSerialIoUartDeviceId (UartNumber)) { + return TRUE; + } + return FALSE; +} + +/** + Configures Serial IO Controller before control is passd to the OS + + @param[in] UartNumber UART Number + @param[in] UartDeviceConfig SerialIo UART Config + +**/ +VOID +SerialIoUartBootHandler ( + IN UINT8 UartNumber, + IN SERIAL_IO_UART_CONFIG *UartDeviceConfig + ) +{ + UINT64 PciCfgBase; + BOOLEAN TurnOff; + + TurnOff = FALSE; + + // + // Even if Uart is Hidden and in D3 SerialIoUartLib is capable of setting D0 during each write/read. + // In case it is required for Os Debug DBG2 must be set to TRUE. + // + if (UartDeviceConfig->Mode == SerialIoUartPci || UartDeviceConfig->Mode == SerialIoUartHidden) { + TurnOff = TRUE; + } + + // + // Uart in Com mode will be placed in D3 depending on PG configuration through ACPI _PS3 + // + + if ((UartDeviceConfig->Mode == SerialIoUartDisabled) && (SerialIoUartFuncNumber (UartNumber) == 0x0)) { + if (SerialIoHigherFunctionsEnabled (SerialIoUartDevNumber (UartNumber))) { + TurnOff = TRUE; + } + } + + if (UartDeviceConfig->DBG2 == TRUE) { + TurnOff = FALSE; + } + + if (TurnOff) { + PciCfgBase = GetSerialIoUartPciCfg (UartNumber); + SerialIoSetD3 (PciCfgBase); + if ((UartDeviceConfig->Mode == SerialIoUartPci) || (UartDeviceConfig->Mode == SerialIoUartDisabled)) { + SerialIoMmioDisable (PciCfgBase, TRUE); + } + } +} + +/** + Sets Pme Control Status and Command register values required for S3 Boot Script + + @param[in] UartNumber UART Number + @param[in] UartDeviceConfig SerialIo UART Config + @param[in/out] S3PciCfgBase S3 Boot Script Pci Config Base + @param[in/out] Command Pci Command register data to save + @param[in/out] Pme Pci Pme Control register data to save + +**/ +VOID +SerialIoUartS3Handler ( + IN UINT8 UartNumber, + IN SERIAL_IO_UART_CONFIG *UartDeviceConfig, + IN OUT UINT64 *S3PciCfgBase, + IN OUT UINT32 *Command, + IN OUT UINT32 *Pme + ) +{ + BOOLEAN TurnOff; + UINT64 PciCfgBase; + + *S3PciCfgBase = 0; + TurnOff = FALSE; + + if (UartDeviceConfig->Mode == SerialIoUartPci) { + TurnOff = TRUE; + } + + if ((UartDeviceConfig->Mode == SerialIoUartDisabled) && (SerialIoUartFuncNumber (UartNumber) == 0x0)) { + if (SerialIoHigherFunctionsEnabled (SerialIoUartDevNumber (UartNumber))) { + TurnOff = TRUE; + } + } + + if (TurnOff) { + *S3PciCfgBase = GetSerialIoUartS3PciBase (UartNumber); + PciCfgBase = GetSerialIoUartPciCfg (UartNumber); + *Pme = PciSegmentRead32 ((UINTN) PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS); + *Pme = *Pme | BIT0 | BIT1; + *Command = PciSegmentRead32 ((UINTN) PciCfgBase + PCI_COMMAND_OFFSET); + *Command = *Command & (UINT32)~(EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER); + } +} diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibUartVer2.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibUartVer2.c new file mode 100644 index 0000000000..91280f8e90 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/SerialIoPrivateLibUartVer2.c @@ -0,0 +1,82 @@ +/** @file + Serial IO Private Uart Lib implementation TigerLake specific. + 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/BaseLib.h> +#include <Library/PchInfoLib.h> +#include <Library/SerialIoAccessLib.h> +#include <Register/SerialIoRegsVer2.h> +#include <IndustryStandard/Pci30.h> +#include <SerialIoPrivateLibInternal.h> +#include <PchReservedResources.h> +#include <PchLimits.h> + +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchLpSerialIoUartDevId [] = { + V_VER2_PCH_LP_SERIAL_IO_CFG_UART0_DEVICE_ID, + V_VER2_PCH_LP_SERIAL_IO_CFG_UART1_DEVICE_ID, + V_VER2_PCH_LP_SERIAL_IO_CFG_UART2_DEVICE_ID, + V_VER2_PCH_LP_SERIAL_IO_CFG_UART3_DEVICE_ID +}; + +GLOBAL_REMOVE_IF_UNREFERENCED SERIAL_IO_CONTROLLER_DESCRIPTOR mSerialIoUartFixedAddress [] = { + {PCH_SERIAL_IO_BASE_ADDRESS + 0x1E000, PCH_SERIAL_IO_BASE_ADDRESS + 0x1F000}, + {PCH_SERIAL_IO_BASE_ADDRESS + 0x20000, PCH_SERIAL_IO_BASE_ADDRESS + 0x21000}, + {PCH_SERIAL_IO_BASE_ADDRESS + 0x22000, PCH_SERIAL_IO_BASE_ADDRESS + 0x23000}, + {PCH_SERIAL_IO_BASE_ADDRESS + 0x24000, PCH_SERIAL_IO_BASE_ADDRESS + 0x25000}, + {PCH_SERIAL_IO_BASE_ADDRESS + 0x26000, PCH_SERIAL_IO_BASE_ADDRESS + 0x27000}, + {PCH_SERIAL_IO_BASE_ADDRESS + 0x28000, PCH_SERIAL_IO_BASE_ADDRESS + 0x29000}, + {PCH_SERIAL_IO_BASE_ADDRESS + 0x2A000, PCH_SERIAL_IO_BASE_ADDRESS + 0x2B000} +}; + +/** + Gets Fixed Base Address used for BAR0 + + @param[in] UartNumber Serial IO device UART number + + @retval Config control offset +**/ +UINT32 +GetSerialIoUartFixedMmioAddress ( + IN UINT8 UartNumber + ) +{ + return mSerialIoUartFixedAddress[UartNumber].Bar0; +} + +/** + Gets Fixed Address used for Pci Config Space manipulation + + @param[in] UartNumber Serial IO device UART number + + @retval Pci Config Address +**/ +UINT32 +GetSerialIoUartFixedPciCfgAddress ( + IN UINT8 UartNumber + ) +{ + return mSerialIoUartFixedAddress[UartNumber].Bar1; +} + +/** + Gets Uarts Device Id + + @param[in] UartNumbe Serial IO device UART number + + @retval Device Id +**/ +UINT16 +GetSerialIoUartDeviceId ( + IN UINT8 UartNumber + ) +{ + return mPchLpSerialIoUartDevId[UartNumber]; +} -- 2.24.0.windows.2 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#70977): https://edk2.groups.io/g/devel/message/70977 Mute This Topic: https://groups.io/mt/80274141/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-