Reviewed-by: Nate DeSimone <nathaniel.l.desim...@intel.com>

> -----Original Message-----
> From: Luo, Heng <heng....@intel.com>
> Sent: Sunday, January 31, 2021 5:37 PM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaga...@intel.com>; Desimone,
> Nathaniel L <nathaniel.l.desim...@intel.com>
> Subject: [PATCH 27/40] TigerlakeSiliconPkg/IpBlock: Add SerialIo component
> 
> 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/Seri
> alIoPrivateLib.h                                    | 377
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++
> 
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/IncludePrivate/Register/Ser
> ialIoRegsVer2.h                                     | 108
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++
> 
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/Library/PeiDxeSmmSerialIo
> AccessLib/PeiDxeSmmSerialIoAccessLib.inf              |  35
> +++++++++++++++++++++++++++++++++++
> 
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/Library/PeiDxeSmmSerialIo
> AccessLib/SerialIoAccessLib.c                         | 266
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++
> 
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmm
> SerialIoPrivateLib/PeiDxeSmmSerialIoPrivateLibVer2.inf |  34
> ++++++++++++++++++++++++++++++++++
> 
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmm
> SerialIoPrivateLib/SerialIoPrivateLib.c                | 156
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++
> 
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmm
> SerialIoPrivateLib/SerialIoPrivateLibI2c.c             | 122
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++
> 
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmm
> SerialIoPrivateLib/SerialIoPrivateLibI2cVer2.c         |  70
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++
> 
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmm
> SerialIoPrivateLib/SerialIoPrivateLibInternal.h        |  20
> ++++++++++++++++++++
> 
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmm
> SerialIoPrivateLib/SerialIoPrivateLibSpi.c             | 122
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++
> 
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmm
> SerialIoPrivateLib/SerialIoPrivateLibSpiVer2.c         |  82
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++
> 
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmm
> SerialIoPrivateLib/SerialIoPrivateLibUart.c            | 136
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++
> 
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmm
> SerialIoPrivateLib/SerialIoPrivateLibUartVer2.c        |  82
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++
>  13 files changed, 1610 insertions(+)
> 
> diff --git
> a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/IncludePrivate/Library/Se
> rialIoPrivateLib.h
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/IncludePrivate/Library/Se
> rialIoPrivateLib.h
> new file mode 100644
> index 0000000000..47057cd2ef
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/IncludePrivate/Library/Se
> rialIoPrivateLib.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/S
> erialIoRegsVer2.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_RegisterS
> pace_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/PeiDxeSmmSerial
> IoAccessLib/PeiDxeSmmSerialIoAccessLib.inf
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/Library/PeiDxeSmmSerial
> IoAccessLib/PeiDxeSmmSerialIoAccessLib.inf
> new file mode 100644
> index 0000000000..9178840ca8
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/Library/PeiDxeSmmSerial
> IoAccessLib/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/PeiDxeSmmSerial
> IoAccessLib/SerialIoAccessLib.c
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/Library/PeiDxeSmmSerial
> IoAccessLib/SerialIoAccessLib.c
> new file mode 100644
> index 0000000000..2b3a3dca5a
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/Library/PeiDxeSmmSerial
> IoAccessLib/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/PeiDxeSm
> mSerialIoPrivateLib/PeiDxeSmmSerialIoPrivateLibVer2.inf
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSm
> mSerialIoPrivateLib/PeiDxeSmmSerialIoPrivateLibVer2.inf
> new file mode 100644
> index 0000000000..8981be2496
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSm
> mSerialIoPrivateLib/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/PeiDxeSm
> mSerialIoPrivateLib/SerialIoPrivateLib.c
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSm
> mSerialIoPrivateLib/SerialIoPrivateLib.c
> new file mode 100644
> index 0000000000..9b84c2dda6
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSm
> mSerialIoPrivateLib/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/PeiDxeSm
> mSerialIoPrivateLib/SerialIoPrivateLibI2c.c
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSm
> mSerialIoPrivateLib/SerialIoPrivateLibI2c.c
> new file mode 100644
> index 0000000000..7601081cfa
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSm
> mSerialIoPrivateLib/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/PeiDxeSm
> mSerialIoPrivateLib/SerialIoPrivateLibI2cVer2.c
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSm
> mSerialIoPrivateLib/SerialIoPrivateLibI2cVer2.c
> new file mode 100644
> index 0000000000..fd684ca2a9
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSm
> mSerialIoPrivateLib/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/PeiDxeSm
> mSerialIoPrivateLib/SerialIoPrivateLibInternal.h
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSm
> mSerialIoPrivateLib/SerialIoPrivateLibInternal.h
> new file mode 100644
> index 0000000000..b5e8aba9ac
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSm
> mSerialIoPrivateLib/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/PeiDxeSm
> mSerialIoPrivateLib/SerialIoPrivateLibSpi.c
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSm
> mSerialIoPrivateLib/SerialIoPrivateLibSpi.c
> new file mode 100644
> index 0000000000..a926941baf
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSm
> mSerialIoPrivateLib/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/PeiDxeSm
> mSerialIoPrivateLib/SerialIoPrivateLibSpiVer2.c
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSm
> mSerialIoPrivateLib/SerialIoPrivateLibSpiVer2.c
> new file mode 100644
> index 0000000000..abda359202
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSm
> mSerialIoPrivateLib/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/PeiDxeSm
> mSerialIoPrivateLib/SerialIoPrivateLibUart.c
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSm
> mSerialIoPrivateLib/SerialIoPrivateLibUart.c
> new file mode 100644
> index 0000000000..0f7d6513ce
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSm
> mSerialIoPrivateLib/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/PeiDxeSm
> mSerialIoPrivateLib/SerialIoPrivateLibUartVer2.c
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSm
> mSerialIoPrivateLib/SerialIoPrivateLibUartVer2.c
> new file mode 100644
> index 0000000000..91280f8e90
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/SerialIo/LibraryPrivate/PeiDxeSm
> mSerialIoPrivateLib/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 (#71164): https://edk2.groups.io/g/devel/message/71164
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]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to