public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers
@ 2021-02-05  7:40 Heng Luo
  2021-02-05  7:40 ` [Patch V3 02/40] TigerlakeSiliconPkg/Include: Add Library, PPI and Protocol include headers Heng Luo
                   ` (38 more replies)
  0 siblings, 39 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Create the TigerlakeSiliconPkg to provide an initial package for
silicon initialization code for Tiger Lake (TGL) products.

* Major areas of functionality are categorized into CPU, IpBlock, Fru,
  Platform Controller Hub (PCH), and System Agent subdirectories.
* Common libraries and headers are kept at the root of the package.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Cnvi/CnviConfig.h                       |   67 ++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/CpuDmi/CpuDmiPreMemConfig.h             |   86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/CpuPcieRp/Gen4/CpuPcieConfig.h          |  498 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Dci/DciConfig.h                         |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Espi/EspiConfig.h                       |   61 ++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Fivr/FivrConfig.h                       |  170 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Gbe/GbeConfig.h                         |   33 +++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Gna/GnaConfig.h                         |   31 ++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Gpio/GpioDevConfig.h                    |   37 ++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Graphics/Gen12/GraphicsConfig.h         |  211 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Hda/HdAudioConfig.h                     |  227 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/HostBridge/HostBridgeConfig.h           |   62 +++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/HybridGraphics/HybridGraphicsConfig.h   |   66 +++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/HybridStorage/HybridStorageConfig.h     |   36 +++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Ieh/IehConfig.h                         |   34 ++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Ish/IshConfig.h                         |  134 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Itss/InterruptConfig.h                  |   58 ++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Itss/IoApicConfig.h                     |   60 +++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Me/MePeiConfig.h                        |  117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Memory/Ver2/MemoryConfig.h              |  478 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Overclocking/OverclockingConfig.h       |  236 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/P2sb/P2sbConfig.h                       |   34 ++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/PchDmi/PchDmiConfig.h                   |   44 +++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/PcieRp/PchPcieRp/PchPcieRpConfig.h      |  368 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/PcieRp/PcieConfig.h                     |  217 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Pmc/AdrConfig.h                         |   86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Pmc/PmConfig.h                          |  391 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Psf/PsfConfig.h                         |   32 ++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Rst/RstConfig.h                         |   82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Rtc/RtcConfig.h                         |   38 +++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Sata/SataConfig.h                       |  168 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Scs/ScsConfig.h                         |  139 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/SerialIo/SerialIoConfig.h               |   32 ++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/SiConfig.h                              |  152 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/SiPreMemConfig.h                        |   67 ++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Smbus/SmbusConfig.h                     |   50 ++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Spi/SpiConfig.h                         |   43 ++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Tcss/TcssPeiConfig.h                    |  145 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Thc/ThcConfig.h                         |   73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Thermal/ThermalConfig.h                 |  153 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/TraceHub/TraceHubConfig.h               |  101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Usb/Usb2PhyConfig.h                     |   81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Usb/Usb3HsioConfig.h                    |  138 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Usb/UsbConfig.h                         |  149 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/VoltageRegulator/CpuPowerMgmtVrConfig.h |  114 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Vtd/VtdConfig.h                         |   64 ++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Wdt/WatchDogConfig.h                    |   31 ++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SiPkg.dec                                                   | 1207 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 48 files changed, 6973 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Cnvi/CnviConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Cnvi/CnviConfig.h
new file mode 100644
index 0000000000..de1f4159f0
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Cnvi/CnviConfig.h
@@ -0,0 +1,67 @@
+/** @file
+  CNVi policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _CNVI_CONFIG_H_
+#define _CNVI_CONFIG_H_
+
+#define CNVI_CONFIG_REVISION 1
+extern EFI_GUID gCnviConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  CNVi Mode options
+**/
+typedef enum {
+  CnviModeDisabled = 0,
+  CnviModeAuto
+} CNVI_MODE;
+
+
+/**
+  CNVi signals pin muxing settings. If signal can be enable only on a single pin
+  then this parameter is ignored by RC. Refer to GPIO_*_MUXING_CNVI_* in GpioPins*.h
+  for supported settings on a given platform
+**/
+typedef struct {
+  UINT32 RfReset; ///< RF_RESET# Pin mux configuration. Refer to GPIO_*_MUXING_CNVI_RF_RESET_*
+  UINT32 Clkreq;  ///< CLKREQ Pin mux configuration. Refer to GPIO_*_MUXING_CNVI_*_CLKREQ_*
+} CNVI_PIN_MUX;
+
+/**
+  The CNVI_CONFIG block describes the expected configuration of the CNVi IP.
+
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;      ///< Config Block Header
+  /**
+    This option allows for automatic detection of Connectivity Solution.
+    Auto Detection assumes that CNVi will be enabled when available;
+    Disable allows for disabling CNVi.
+    CnviModeDisabled = Disabled,
+    <b>CnviModeAuto = Auto Detection</b>
+  **/
+  UINT32 Mode                  :  1;
+  UINT32 BtCore                :  1; ///< The option to turn ON or OFF the BT Core. 0: Disabled, <b>1: Enabled</b>
+  /**
+    The option to enable or disable BT Audio Offload.
+    <b>0: Disabled</b>, 1: Enabled
+    @note This feature only support with Intel(R) Wireless-AX 22560
+  **/
+  UINT32 BtAudioOffload        :  1;
+  UINT32 RsvdBits              : 29;
+  /**
+    CNVi PinMux Configuration
+    RESET#/CLKREQ to CRF, can have two alternative mappings, depending on board routing requirements.
+  **/
+  CNVI_PIN_MUX          PinMux;
+} CNVI_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CNVI_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/CpuDmi/CpuDmiPreMemConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/CpuDmi/CpuDmiPreMemConfig.h
new file mode 100644
index 0000000000..527febb0a4
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/CpuDmi/CpuDmiPreMemConfig.h
@@ -0,0 +1,86 @@
+/** @file
+  DMI policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _CPU_DMI_PREMEM_CONFIG_H_
+#define _CPU_DMI_PREMEM_CONFIG_H_
+
+#include <ConfigBlock.h>
+#include <Register/SaRegsHostBridge.h>
+
+#define DMI_CONFIG_REVISION 1
+
+#define CPU_DMI_HWEQ_COEFFS_MAX    8
+
+#pragma pack (push,1)
+///
+/// The values before AutoConfig match the setting of PCI Express Base Specification 1.1, please be careful for adding new feature
+///
+typedef enum {
+  DmiAspmDisabled,
+  DmiAspmL0s,
+  DmiAspmL1,
+  DmiAspmL0sL1,
+  DmiAspmAutoConfig,
+  DmiAspmMax
+} DMI_ASPM;
+
+
+/**
+  The CPU_DMI_CONFIG block describes the expected configuration of the CPU for DMI.
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header
+
+/**
+  - <b>Auto</b> (0x0)  : Maximum possible link speed (Default)
+  - Gen1        (0x1)  : Limit Link to Gen1 Speed
+  - Gen2        (0x2)  : Limit Link to Gen2 Speed    CpuDmiPreMemConfig
+  - Gen3        (0x3)  : Limit Link to Gen3 Speed
+  **/
+  UINT8                  DmiMaxLinkSpeed;
+  /**
+   <b>(Test)</b> DMI Equalization Phase 2 Enable Control
+  - Disabled       (0x0) : Disable phase 2
+  - Enabled        (0x1) : Enable phase 2
+  - <b>Auto</b>    (0x2) : Use the current default method (Default)
+  **/
+  UINT8                  DmiGen3EqPh2Enable;
+  /**
+   <b>(Test)</b> Selects the method for performing Phase3 of Gen3 Equalization on DMI
+  - <b>Auto</b> (0x0)  : Use the current default method (Default)
+  - HwEq        (0x1)  : Use Adaptive Hardware Equalization
+  - SwEq        (0x2)  : Use Adaptive Software Equalization (Implemented in BIOS Reference Code)
+  - Static      (0x3)  : Use the Static EQs provided in DmiGen3EndPointPreset array for Phase1 AND Phase3 (Instead of just Phase1)
+  - Disabled    (0x4)  : Bypass Equalization Phase 3
+  **/
+  UINT8                  DmiGen3EqPh3Method;
+  /**
+   <b>(Test)</b> Program DMI Gen3 EQ Phase1 Static Presets
+  - Disabled        (0x0)  : Disable EQ Phase1 Static Presets Programming
+  - <b>Enabled</b>  (0x1)  : Enable  EQ Phase1 Static Presets Programming (Default)
+  **/
+  UINT8                  DmiGen3ProgramStaticEq;
+  UINT8                  DmiDeEmphasis;                               ///< DeEmphasis control for DMI (-6 dB and -3.5 dB are the options)
+  UINT8                  DmiAspm;
+  UINT8                  DmiAspmCtrl;                                 ///< ASPM configuration on the CPU side of the DMI/OPI Link. Default is <b>DmiAspmAutoConfig</b>
+  UINT8                  DmiAspmL1ExitLatency;                        ///< ASPM configuration on the CPU side of the DMI/OPI Link. Default is <b>DmiAspmAutoConfig</b>
+  UINT8                  DmiGen3RootPortPreset[SA_DMI_MAX_LANE];      ///< Used for programming DMI Gen3 preset values per lane. Range: 0-9, 8 is default for each lane
+  UINT8                  DmiGen3EndPointPreset[SA_DMI_MAX_LANE];      ///< Used for programming DMI Gen3 preset values per lane. Range: 0-9, 7 is default for each lane
+  UINT8                  DmiGen3EndPointHint[SA_DMI_MAX_LANE];        ///< Hint value per lane for the DMI Gen3 End Point. Range: 0-6, 2 is default for each lane
+
+  /**
+   DMI Gen3 RxCTLEp per-Bundle control. The range of the setting is (0-15). This setting
+   has to be specified based upon platform design and must follow the guideline. Default is 12.
+  **/
+
+  UINT8                  DmiGen3RxCtlePeaking[SA_DMI_MAX_BUNDLE];
+} CPU_DMI_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_DMI_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/CpuPcieRp/Gen4/CpuPcieConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/CpuPcieRp/Gen4/CpuPcieConfig.h
new file mode 100644
index 0000000000..f18cd0352a
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/CpuPcieRp/Gen4/CpuPcieConfig.h
@@ -0,0 +1,498 @@
+/** @file
+  Pcie root port policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_PCIE_CONFIG_H_
+#define _CPU_PCIE_CONFIG_H_
+
+#include <Library/GpioLib.h>
+#include <Library/CpuPcieInfoFruLib.h>
+#include <PcieConfig.h>
+#include <ConfigBlock.h>
+#include <Register/SaRegsHostBridge.h>
+
+#pragma pack(push, 1)
+
+#define CPU_PCIE_PEI_PREMEM_CONFIG_REVISION 1
+#define CPU_PCIE_RP_PREMEM_CONFIG_REVISION  4
+
+/**
+ Making any setup structure change after code frozen
+ will need to maintain backward compatibility, bump up
+ structure revision and update below history table\n
+  <b>Revision 1</b>:  - Initial version.
+  <b>Revision 2</b>:  - Add Gen3TxOverride and Gen4TxOverride
+  <b>Revision 3</b>:  - Deprecate Dekel Suqelch Workaround Setup Variable
+  <b>Revision 4</b>:  - Add FOMS Control Policy Setup Variable
+  <b>Revision 5</b>:  - Add Gen3HwEqOverride and Gen4HwEqOverride
+  <b>Revision 6</b>:  - Align revision with CPU_PCIE_RP_CONFIG_REVISION value
+**/
+
+#define CPU_PCIE_RP_CONFIG_REVISION         6
+
+#define L0_SET                            BIT0
+#define L1_SET                            BIT1
+
+
+
+
+/**
+ PCI Express and DMI controller configuration\n
+ @note <b>Optional.</b> These policies will be ignored if there is no PEG port present on board.
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER    Header;                                      ///< Offset 0-27 Config Block Header
+  /**
+   Offset 28:0 :
+   <b>(Test)</b> DMI Link Speed Control
+  - <b>Auto</b> (0x0)  : Maximum possible link speed (Default)
+  - Gen1        (0x1)  : Limit Link to Gen1 Speed
+  - Gen2        (0x2)  : Limit Link to Gen2 Speed
+  - Gen3        (0x3)  : Limit Link to Gen3 Speed
+  **/
+  UINT32                 DmiMaxLinkSpeed                 :  2;
+  /**
+   Offset 28:2 :
+   <b>(Test)</b> DMI Equalization Phase 2 Enable Control
+  - Disabled       (0x0) : Disable phase 2
+  - Enabled        (0x1) : Enable phase 2
+  - <b>Auto</b>    (0x2) : Use the current default method (Default)
+  **/
+  UINT32                 DmiGen3EqPh2Enable              :  2;
+  /**
+   Offset 28:4 :
+   <b>(Test)</b> Selects the method for performing Phase3 of Gen3 Equalization on DMI
+  - <b>Auto</b> (0x0)  : Use the current default method (Default)
+  - HwEq        (0x1)  : Use Adaptive Hardware Equalization
+  - SwEq        (0x2)  : Use Adaptive Software Equalization (Implemented in BIOS Reference Code)
+  - Static      (0x3)  : Use the Static EQs provided in DmiGen3EndPointPreset array for Phase1 AND Phase3 (Instead of just Phase1)
+  - Disabled    (0x4)  : Bypass Equalization Phase 3
+  **/
+  UINT32                 DmiGen3EqPh3Method              :  3;
+  /**
+   Offset 28:7 :
+   <b>(Test)</b> Program DMI Gen3 EQ Phase1 Static Presets
+  - Disabled        (0x0)  : Disable EQ Phase1 Static Presets Programming
+  - <b>Enabled</b>  (0x1)  : Enable  EQ Phase1 Static Presets Programming (Default)
+  **/
+  UINT32                 DmiGen3ProgramStaticEq          :  1;
+  UINT32                 RsvdBits0                       :  24;        ///< Offset 28:8 :Reserved for future use
+
+  /**
+  Offset 32:0 :
+  Select when PCIe ASPM programming will happen in relation to the Oprom
+  - <b>Before</b> (0x0) : Do PCIe ASPM programming before Oprom. (Default)
+  - After         (0x1) : Do PCIe ASPM programming after Oprom. This will require an SMI handler to save/restore ASPM settings.
+  **/
+  UINT32                 InitPcieAspmAfterOprom : 1;
+  UINT32                 RsvdBits1 : 31;        ///< Offset 32:1 :Reserved for future use
+
+  UINT8                  DmiGen3RootPortPreset[SA_DMI_MAX_LANE];      ///< Offset 36 Used for programming DMI Gen3 preset values per lane. Range: 0-9, 8 is default for each lane
+  UINT8                  DmiGen3EndPointPreset[SA_DMI_MAX_LANE];      ///< Offset 40/44 Used for programming DMI Gen3 preset values per lane. Range: 0-9, 7 is default for each lane
+  UINT8                  DmiGen3EndPointHint[SA_DMI_MAX_LANE];        ///< Offset 44/52 Hint value per lane for the DMI Gen3 End Point. Range: 0-6, 2 is default for each lane
+  /**
+   Offset 48/60 :
+   DMI Gen3 RxCTLEp per-Bundle control. The range of the setting is (0-15). This setting
+   has to be specified based upon platform design and must follow the guideline. Default is 12.
+  **/
+
+  UINT8                  DmiGen3RxCtlePeaking[SA_DMI_MAX_BUNDLE];
+
+  UINT8                  DmiDeEmphasis;                               ///< Offset 64 This field is used to describe the DeEmphasis control for DMI (-6 dB and -3.5 dB are the options)
+  UINT8                  Rsvd0[3];                                    ///< Offset 65
+} PCIE_PEI_PREMEM_CONFIG;
+
+
+/**
+  CPU PCIe Root Port Pre-Memory Configuration
+  Contains Root Port settings and capabilities
+  <b>Revision 1</b>:  - Initial version.
+  <b>Revision 2</b>:  - Adding Dekel Suqelch Workaround Setup Variable
+  <b>Revision 3</b>:  - Deprecate Dekel Suqelch Workaround Setup Variable
+  <b>Revision 4</b>:  - Adding CDR Relock Setup Variable
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                                ///< Config Block Header
+  /**
+  Root Port enabling mask.
+  Bit0 presents RP1, Bit1 presents RP2, and so on.
+  0: Disable; <b>1: Enable</b>.
+  **/
+  UINT32                RpEnabledMask;
+  /**
+  Assertion on Link Down GPIOs
+  - <b>Disabled</b> (0x0) : Disable assertion on Link Down GPIOs(Default)
+  - Enabled         (0x1) : Enable assertion on Link Down GPIOs
+  **/
+  UINT8                 LinkDownGpios;
+  /**
+  Enable ClockReq Messaging
+  - <b>Disabled</> (0x0) : Disable ClockReq Messaging(Default)
+  - Enabled        (0x1) : Enable ClockReq Messaging
+  **/
+  UINT8                 ClkReqMsgEnable;
+  /**
+  Dekel Recipe Workaround
+  <b>2</b>
+  1=Minimal, 9=Maximum,
+  **/
+  UINT8                 DekelSquelchWa;  // Deprecated variable
+  UINT8                 Rsvd0[1];
+  /**
+  Determines each PCIE Port speed capability.
+  <b>0: Auto</b>; 1: Gen1; 2: Gen2; 3: Gen3; 4: Gen4 (see: CPU_PCIE_SPEED)
+  **/
+  UINT8                 PcieSpeed[CPU_PCIE_MAX_ROOT_PORTS];
+  /**
+  To Enable/Disable CDR Relock
+  <b>0: Disable</b>; 1: Enable
+  **/
+  UINT8                 CdrRelock[CPU_PCIE_MAX_ROOT_PORTS];
+  /**
+  This policy is used while programming DEKEL Recipe
+  <b>0: Disable</b>; 1: Enable
+  **/
+  UINT8                 Xl1el[CPU_PCIE_MAX_ROOT_PORTS];
+
+} CPU_PCIE_RP_PREMEM_CONFIG;
+
+typedef enum {
+  CpuPcieOverrideDisabled             = 0,
+  CpuPcieL1L2Override                 = 0x01,
+  CpuPcieL1SubstatesOverride          = 0x02,
+  CpuPcieL1L2AndL1SubstatesOverride   = 0x03,
+  CpuPcieLtrOverride                  = 0x04
+} CPU_PCIE_OVERRIDE_CONFIG;
+
+/**
+  PCIe device table entry entry
+
+  The PCIe device table is being used to override PCIe device ASPM settings.
+  To take effect table consisting of such entries must be instelled as PPI
+  on gPchPcieDeviceTablePpiGuid.
+  Last entry VendorId must be 0.
+**/
+typedef struct {
+  UINT16  VendorId;                    ///< The vendor Id of Pci Express card ASPM setting override, 0xFFFF means any Vendor ID
+  UINT16  DeviceId;                    ///< The Device Id of Pci Express card ASPM setting override, 0xFFFF means any Device ID
+  UINT8   RevId;                       ///< The Rev Id of Pci Express card ASPM setting override, 0xFF means all steppings
+  UINT8   BaseClassCode;               ///< The Base Class Code of Pci Express card ASPM setting override, 0xFF means all base class
+  UINT8   SubClassCode;                ///< The Sub Class Code of Pci Express card ASPM setting override, 0xFF means all sub class
+  UINT8   EndPointAspm;                ///< Override device ASPM (see: CPU_PCIE_ASPM_CONTROL)
+                                       ///< Bit 1 must be set in OverrideConfig for this field to take effect
+  UINT16  OverrideConfig;              ///< The override config bitmap (see: CPU_PCIE_OVERRIDE_CONFIG).
+  /**
+    The L1Substates Capability Offset Override. (applicable if bit 2 is set in OverrideConfig)
+    This field can be zero if only the L1 Substate value is going to be override.
+  **/
+  UINT16  L1SubstatesCapOffset;
+  /**
+    L1 Substate Capability Mask. (applicable if bit 2 is set in OverrideConfig)
+    Set to zero then the L1 Substate Capability [3:0] is ignored, and only L1s values are override.
+    Only bit [3:0] are applicable. Other bits are ignored.
+  **/
+  UINT8   L1SubstatesCapMask;
+  /**
+    L1 Substate Port Common Mode Restore Time Override. (applicable if bit 2 is set in OverrideConfig)
+    L1sCommonModeRestoreTime and L1sTpowerOnScale can have a valid value of 0, but not the L1sTpowerOnValue.
+    If L1sTpowerOnValue is zero, all L1sCommonModeRestoreTime, L1sTpowerOnScale, and L1sTpowerOnValue are ignored,
+    and only L1SubstatesCapOffset is override.
+  **/
+  UINT8   L1sCommonModeRestoreTime;
+  /**
+    L1 Substate Port Tpower_on Scale Override. (applicable if bit 2 is set in OverrideConfig)
+    L1sCommonModeRestoreTime and L1sTpowerOnScale can have a valid value of 0, but not the L1sTpowerOnValue.
+    If L1sTpowerOnValue is zero, all L1sCommonModeRestoreTime, L1sTpowerOnScale, and L1sTpowerOnValue are ignored,
+    and only L1SubstatesCapOffset is override.
+  **/
+  UINT8   L1sTpowerOnScale;
+  /**
+    L1 Substate Port Tpower_on Value Override. (applicable if bit 2 is set in OverrideConfig)
+    L1sCommonModeRestoreTime and L1sTpowerOnScale can have a valid value of 0, but not the L1sTpowerOnValue.
+    If L1sTpowerOnValue is zero, all L1sCommonModeRestoreTime, L1sTpowerOnScale, and L1sTpowerOnValue are ignored,
+    and only L1SubstatesCapOffset is override.
+  **/
+  UINT8   L1sTpowerOnValue;
+
+  /**
+    SnoopLatency bit definition
+    Note: All Reserved bits must be set to 0
+
+    BIT[15]     - When set to 1b, indicates that the values in bits 9:0 are valid
+                  When clear values in bits 9:0 will be ignored
+    BITS[14:13] - Reserved
+    BITS[12:10] - Value in bits 9:0 will be multiplied with the scale in these bits
+                  000b - 1 ns
+                  001b - 32 ns
+                  010b - 1024 ns
+                  011b - 32,768 ns
+                  100b - 1,048,576 ns
+                  101b - 33,554,432 ns
+                  110b - Reserved
+                  111b - Reserved
+    BITS[9:0]   - Snoop Latency Value. The value in these bits will be multiplied with
+                  the scale in bits 12:10
+
+    This field takes effect only if bit 3 is set in OverrideConfig.
+  **/
+  UINT16  SnoopLatency;
+  /**
+    NonSnoopLatency bit definition
+    Note: All Reserved bits must be set to 0
+
+    BIT[15]     - When set to 1b, indicates that the values in bits 9:0 are valid
+                  When clear values in bits 9:0 will be ignored
+    BITS[14:13] - Reserved
+    BITS[12:10] - Value in bits 9:0 will be multiplied with the scale in these bits
+                  000b - 1 ns
+                  001b - 32 ns
+                  010b - 1024 ns
+                  011b - 32,768 ns
+                  100b - 1,048,576 ns
+                  101b - 33,554,432 ns
+                  110b - Reserved
+                  111b - Reserved
+    BITS[9:0]   - Non Snoop Latency Value. The value in these bits will be multiplied with
+                  the scale in bits 12:10
+
+    This field takes effect only if bit 3 is set in OverrideConfig.
+  **/
+  UINT16  NonSnoopLatency;
+
+  /**
+    Forces LTR override to be permanent
+    The default way LTR override works is:
+      rootport uses LTR override values provided by BIOS until connected device sends an LTR message, then it will use values from the message
+    This settings allows force override of LTR mechanism. If it's enabled, then:
+      rootport will use LTR override values provided by BIOS forever; LTR messages sent from connected device will be ignored
+  **/
+  UINT8  ForceLtrOverride;
+  UINT8  Reserved[3];
+} CPU_PCIE_DEVICE_OVERRIDE;
+
+enum CPU_PCIE_SPEED {
+  CpuPcieAuto,
+  CpuPcieGen1,
+  CpuPcieGen2,
+  CpuPcieGen3,
+  CpuPcieGen4,
+  CpuPcieGen5
+};
+
+///
+/// The values before AutoConfig match the setting of PCI Express Base Specification 1.1, please be careful for adding new feature
+///
+typedef enum {
+  CpuPcieAspmDisabled,
+  CpuPcieAspmL0s,
+  CpuPcieAspmL1,
+  CpuPcieAspmL0sL1,
+  CpuPcieAspmAutoConfig,
+  CpuPcieAspmMax
+} CPU_PCIE_ASPM_CONTROL;
+
+/**
+  Refer to SA EDS for the SA implementation values corresponding
+  to below PCI-E spec defined ranges
+**/
+typedef enum {
+  CpuPcieL1SubstatesDisabled,
+  CpuPcieL1SubstatesL1_1,
+  CpuPcieL1SubstatesL1_1_2,
+  CpuPcieL1SubstatesMax
+} CPU_PCIE_L1SUBSTATES_CONTROL;
+
+enum CPU_PCIE_MAX_PAYLOAD {
+  CpuPcieMaxPayload128 = 0,
+  CpuPcieMaxPayload256,
+  CpuPcieMaxPayload512,
+  CpuPcieMaxPayloadMax
+};
+
+enum CPU_PCIE_COMPLETION_TIMEOUT {
+  CpuPcieCompletionTO_Default,
+  CpuPcieCompletionTO_50_100us,
+  CpuPcieCompletionTO_1_10ms,
+  CpuPcieCompletionTO_16_55ms,
+  CpuPcieCompletionTO_65_210ms,
+  CpuPcieCompletionTO_260_900ms,
+  CpuPcieCompletionTO_1_3P5s,
+  CpuPcieCompletionTO_4_13s,
+  CpuPcieCompletionTO_17_64s,
+  CpuPcieCompletionTO_Disabled
+};
+
+
+enum CPU_PCIE_GEN3_PRESET_COEFF_SELECTION {
+  CpuPcieGen3PresetSelection,
+  CpuPcieGen3CoefficientSelection
+};
+
+enum CPU_PCIE_GEN4_PRESET_COEFF_SELECTION {
+  CpuPcieGen4PresetSelection,
+  CpuPcieGen4CoefficientSelection
+};
+
+typedef enum {
+  CpuPcieEqDefault      = 0,  ///< @deprecated since revision 3. Behaves as PchPcieEqHardware.
+  CpuPcieEqHardware     = 1,  ///< Hardware equalization
+  CpuPcieEqStaticCoeff  = 4   ///< Fixed equalization (requires Coefficient settings per lane)
+} CPU_PCIE_EQ_METHOD;
+
+
+/**
+  Represent lane specific PCIe Gen3 equalization parameters.
+**/
+typedef struct {
+  UINT8                  Cm;                 ///< Coefficient C-1
+  UINT8                  Cp;                 ///< Coefficient C+1
+  UINT8                  PegGen3RootPortPreset;      ///< <b>(Test)</b> Used for programming PEG Gen3 preset values per lane. Range: 0-9, 8 is default for each lane
+  UINT8                  PegGen3EndPointPreset;      ///< <b>(Test)</b> Used for programming PEG Gen3 preset values per lane. Range: 0-9, 7 is default for each lane
+  UINT8                  PegGen3EndPointHint;        ///< <b>(Test)</b> Hint value per lane for the PEG Gen3 End Point. Range: 0-6, 2 is default for each lane
+  UINT8                  PegGen4RootPortPreset;      ///< <b>(Test)</b> Used for programming PEG Gen4 preset values per lane. Range: 0-9, 8 is default for each lane
+  UINT8                  PegGen4EndPointPreset;      ///< <b>(Test)</b> Used for programming PEG Gen4 preset values per lane. Range: 0-9, 7 is default for each lane
+  UINT8                  PegGen4EndPointHint;        ///< <b>(Test)</b> Hint value per lane for the PEG Gen4 End Point. Range: 0-6, 2 is default for each lane
+} CPU_PCIE_EQ_LANE_PARAM;
+
+/**
+  The CPU_PCI_ROOT_PORT_CONFIG describe the feature and capability of each CPU PCIe root port.
+**/
+typedef struct {
+
+  UINT32  ExtSync                         :  1;   ///< Indicate whether the extended synch is enabled. <b>0: Disable</b>; 1: Enable.
+  UINT32  VcEnabled                       :  1;   ///< Virtual Channel. 0: Disable; <b>1: Enable</b>
+  UINT32  MultiVcEnabled                  :  1;   ///< Multiple Virtual Channel. 0: Disable; <b>1: Enable</b>
+  UINT32  PeerToPeer                      :  1;   ///< Peer to Peer Mode. <b>0: Disable</b>; 1: Enable.
+  UINT32  RsvdBits0                       : 28;   ///< Reserved bits
+  /**
+  PCIe Gen4 Equalization Method
+  - HwEq           (0x1) : Hardware Equalization (Default)
+  - StaticEq       (0x2) : Static Equalization
+  **/
+  UINT8   Gen4EqPh3Method;
+  UINT8   FomsCp;                                 ///< FOM Score Board Control Policy
+  UINT8   RsvdBytes0[2];                          ///< Reserved bytes
+
+  //
+  // Gen3 Equalization settings
+  //
+  UINT32  Gen3Uptp            :  4;               ///< <b>(Test)</b> Upstream Port Transmitter Preset used during Gen3 Link Equalization. Used for all lanes.  Default is <b>7</b>.
+  UINT32  Gen3Dptp            :  4;               ///< <b>(Test)</b> Downstream Port Transmiter Preset used during Gen3 Link Equalization. Used for all lanes.  Default is <b>7</b>.
+  //
+  // Gen4 Equalization settings
+  //
+  UINT32  Gen4Uptp            :  4;               ///< <b>(Test)</b> Upstream Port Transmitter Preset used during Gen4 Link Equalization. Used for all lanes.  Default is <b>7</b>.
+  UINT32  Gen4Dptp            :  4;               ///< <b>(Test)</b> Downstream Port Transmiter Preset used during Gen4 Link Equalization. Used for all lanes.  Default is <b>7</b>.
+  //
+  // Gen5 Equalization settings
+  //
+  UINT32  Gen5Uptp            :  4;               ///< <b>(Test)</b> Upstream Port Transmitter Preset used during Gen5 Link Equalization. Used for all lanes.  Default is <b>7</b>.
+  UINT32  Gen5Dptp            :  4;               ///< <b>(Test)</b> Downstream Port Transmiter Preset used during Gen5 Link Equalization. Used for all lanes.  Default is <b>7</b>.
+  UINT32  RsvdBits1           :  8;               ///< Reserved Bits
+
+  PCIE_ROOT_PORT_COMMON_CONFIG                    PcieRpCommonConfig;                       ///< <b>(Test)</b> Includes policies which are common to both SA and PCH RootPort
+
+} CPU_PCIE_ROOT_PORT_CONFIG;
+
+typedef struct {
+  UINT8   PcieGen3PresetCoeffSelection;           ///<Gen3 Preset or Coefficient Selection
+  UINT8   PcieGen4PresetCoeffSelection;           ///<Gen4 Preset or Coefficient Selection
+  UINT8   RsvdBytes0[2];                          ///<Reserved bytes
+} CPU_PCIE_ROOT_PORT_CONFIG2;
+
+/**
+  The CPU_PCIE_CONFIG block describes the expected configuration of the CPU PCI Express controllers
+  <b>Revision 1< / b>:
+  -Initial version.
+  <b>Revision 2</b>:
+  - SlotSelection policy added
+  <b>Revision 3</b>
+  - Deprecate PegGen3ProgramStaticEq and PegGen4ProgramStaticEq
+  <b>Revision 4</b>:
+  - Deprecating SetSecuredRegisterLock
+  <b>Revision 5</b>:
+  - Adding Serl
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER               Header;                   ///< Config Block Header
+  ///
+  /// These members describe the configuration of each SA PCIe root port.
+  ///
+  CPU_PCIE_ROOT_PORT_CONFIG         RootPort[CPU_PCIE_MAX_ROOT_PORTS];
+  ///
+  /// Gen3 Equalization settings for physical PCIe lane, index 0 represents PCIe lane 1, etc.
+  /// Corresponding entries are used when root port EqPh3Method is PchPcieEqStaticCoeff (default).
+  ///
+  CPU_PCIE_EQ_LANE_PARAM            EqPh3LaneParam[SA_PEG_MAX_LANE];
+  ///
+  /// List of coefficients used during equalization (applicable to both software and hardware EQ)
+  ///
+  PCIE_EQ_PARAM                     HwEqGen4CoeffList[PCIE_HWEQ_COEFFS_MAX];  // Deprecated Policy
+
+  PCIE_COMMON_CONFIG                PcieCommonConfig;   /// < <b>(Test)</b> Includes policies which are common to both SA and PCH PCIe
+
+  UINT32  FiaProgramming                  :  1;        /// < Skip Fia Configuration and lock if enable
+  ///
+  /// This member describes whether the PCI Express Clock Gating for each root port
+  /// is enabled by platform modules. <b>0: Disable</b>; 1: Enable.
+  ///
+  UINT32  ClockGating                     :  1;
+  ///
+  /// This member describes whether the PCI Express Power Gating for each root port
+  /// is enabled by platform modules. <b>0: Disable</b>; 1: Enable.
+  ///
+  UINT32  PowerGating                     :  1;
+  // Deprecated Policy
+  /**
+    <b>(Test)</b> Program PEG Gen3 EQ Phase1 Static Presets
+  - Disabled        (0x0)  : Disable EQ Phase1 Static Presets Programming
+  - <b>Enabled</b>  (0x1)  : Enable  EQ Phase1 Static Presets Programming (Default)
+  **/
+  UINT32  PegGen3ProgramStaticEq          :  1;
+
+  // Deprecated Policy
+  /**
+  <b>(Test)</b> Program PEG Gen4 EQ Phase1 Static Presets
+  - Disabled        (0x0)  : Disable EQ Phase1 Static Presets Programming
+  - <b>Enabled</b>  (0x1)  : Enable  EQ Phase1 Static Presets Programming (Default)
+  **/
+  UINT32  PegGen4ProgramStaticEq          :  1;
+  /**
+  <b>(Test)</b> Cpu Pcie Secure Register Lock
+  - Disabled        (0x0)
+  - <b>Enabled</b>  (0x1)
+  **/
+  UINT32  SetSecuredRegisterLock          :  1;  // Deprecated Policy
+  ///
+  /// This member allows to select between the PCI Express M2 or CEMx4 slot <b>1: PCIe M2</b>; 0: CEMx4 slot.
+  ///
+  UINT32  SlotSelection                   :  1;
+  ///
+  /// Set/Clear Serl(Secure Equalization Register Lock)
+  ///
+  UINT32  Serl                            :  1;
+
+  UINT32  RsvdBits0                       : 24;
+
+  /**
+    PCIe device override table
+    The PCIe device table is being used to override PCIe device ASPM settings.
+    This is a pointer points to a 32bit address. And it's only used in PostMem phase.
+    Please refer to PCH_PCIE_DEVICE_OVERRIDE structure for the table.
+    Last entry VendorId must be 0.
+    The prototype of this policy is:
+    CPU_PCIE_DEVICE_OVERRIDE *PcieDeviceOverrideTablePtr;
+  **/
+  UINT32  PcieDeviceOverrideTablePtr;
+  CPU_PCIE_ROOT_PORT_CONFIG2         RootPort2[CPU_PCIE_MAX_ROOT_PORTS];
+  PCIE_COMMON_CONFIG2                PcieCommonConfig2;
+} CPU_PCIE_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_PCIE_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Dci/DciConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Dci/DciConfig.h
new file mode 100644
index 0000000000..445642da1f
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Dci/DciConfig.h
@@ -0,0 +1,72 @@
+/** @file
+  Dci policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _DCI_CONFIG_H_
+#define _DCI_CONFIG_H_
+
+#define DCI_PREMEM_CONFIG_REVISION 2
+extern EFI_GUID gDciPreMemConfigGuid;
+
+#pragma pack (push,1)
+
+typedef enum {
+  DciDbcDisabled       = 0x0,
+  DciDbcUsb2           = 0x1,
+  DciDbcUsb3           = 0x2,
+  DciDbcBoth           = 0x3,
+  DciDbcNoChange       = 0x4,
+  DciDbcMax
+} DCI_DBC_MODE;
+
+typedef enum {
+  Usb3TcDbgDisabled    = 0x0,
+  Usb3TcDbgEnabled     = 0x1,
+  Usb3TcDbgNoChange    = 0x2,
+  Usb3TcDbgMax
+} DCI_USB3_TYPE_C_DEBUG_MODE;
+
+/**
+  The PCH_DCI_PREMEM_CONFIG block describes policies related to Direct Connection Interface (DCI)
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Added DciModphyPg
+  - change to use data in byte unit rather than bit-field
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header
+  /**
+    DCI enable.
+    Determine if to enable DCI debug from host.
+    <b>0:Disabled</b>; 1:Enabled
+  **/
+  UINT8    DciEn;
+  /**
+    USB DbC enable mode.
+    Disabled: Clear both USB2/3DBCEN; USB2: Set USB2DBCEN; USB3: Set USB3DBCEN; Both: Set both USB2/3DBCEN; No Change: Comply with HW value
+    Refer to definition of DCI_USB_DBC_MODE for supported settings.
+    0:Disabled; 1:USB2; 2:USB3; 3:Both; <b>4:No Change</b>
+  **/
+  UINT8    DciDbcMode;
+  /**
+    Enable Modphy power gate when DCI is enable. It must be disabled for 4-wire DCI OOB. Set default to HW default : Disabled
+    <b>0:Disabled</b>; 1:Enabled
+  **/
+  UINT8    DciModphyPg;
+  /**
+    USB3 Type-C UFP2DFP kenel / platform debug support. No change will do nothing to UFP2DFP configuration.
+    When enabled, USB3 Type C UFP (upstream-facing port) may switch to DFP (downstream-facing port) for first connection.
+    It must be enabled for USB3 kernel(kernel mode debug) and platform debug(DFx, DMA, Trace) over UFP Type-C receptacle.
+    Refer to definition of DCI_USB_TYPE_C_DEBUG_MODE for supported settings.
+    0:Disabled; 1:Enabled; <b>2:No Change</b>
+  **/
+  UINT8    DciUsb3TypecUfpDbg;
+} PCH_DCI_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _DCI_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Espi/EspiConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Espi/EspiConfig.h
new file mode 100644
index 0000000000..260b582702
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Espi/EspiConfig.h
@@ -0,0 +1,61 @@
+/** @file
+  Espi policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _ESPI_CONFIG_H_
+#define _ESPI_CONFIG_H_
+
+#define ESPI_CONFIG_REVISION 2
+extern EFI_GUID gEspiConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  This structure contains the policies which are related to ESPI.
+
+  <b>Revision 1</b>:
+  - Initial revision
+  <b>Revision 2</b>:
+  - Added LockLinkConfiguration field to config block
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  /**
+    LPC (eSPI) Memory Range Decode Enable. When TRUE, then the range
+    specified in PCLGMR[31:16] is enabled for decoding to LPC (eSPI).
+    <b>0: FALSE</b>, 1: TRUE
+  **/
+  UINT32    LgmrEnable            :  1;
+  /**
+    eSPI Master and Slave BME settings.
+    When TRUE, then the BME bit enabled in eSPI Master and Slave.
+    0: FALSE, <b>1: TRUE </b>
+  **/
+  UINT32    BmeMasterSlaveEnabled :  1;
+  /**
+    Master HOST_C10 (Virtual Wire) to Slave Enable (VWHC10OE)
+    <b>0b: Disable HOST_C10 reporting (HOST_C10 indication from PMC is ignored)</b>
+    1b: Enable HOST_C10 reporting to Slave via eSPI Virtual Wire (upon receiving a HOST_C10 indication from PMC)
+  **/
+  UINT32    HostC10ReportEnable   :  1;
+  /**
+    eSPI Link Configuration Lock (SBLCL)
+    If set to TRUE then communication through SET_CONFIG/GET_CONFIG
+    to eSPI slaves addresses from range 0x0 - 0x7FF
+    <b>1: TRUE</b>, 0: FALSE
+  **/
+  UINT32    LockLinkConfiguration :  1;
+  /**
+   Hardware Autonomous Enable (HAE)
+   If set to TRUE, then the IP may request a PG whenever it is idle
+  **/
+  UINT32    EspiPmHAE             :  1;
+  UINT32    RsvdBits              : 27;     ///< Reserved bits
+} PCH_ESPI_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _ESPI_CONFIG_H_
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Fivr/FivrConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Fivr/FivrConfig.h
new file mode 100644
index 0000000000..0df2755280
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Fivr/FivrConfig.h
@@ -0,0 +1,170 @@
+/** @file
+  PCH FIVR policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _FIVR_CONFIG_H_
+#define _FIVR_CONFIG_H_
+
+#define FIVR_CONFIG_REVISION 1
+extern EFI_GUID gFivrConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  Rail support in S0ix and Sx
+  Settings other than FivrRailDisabled can be OR'ed
+**/
+typedef enum {
+  FivrRailDisabled   = 0,
+  FivrRailInS0i1S0i2 = BIT0,
+  FivrRailInS0i3     = BIT1,
+  FivrRailInS3       = BIT2,
+  FivrRailInS4       = BIT3,
+  FivrRailInS5       = BIT4,
+  FivrRailInS0ix     = FivrRailInS0i1S0i2 | FivrRailInS0i3,
+  FivrRailInSx       = FivrRailInS3 | FivrRailInS4 | FivrRailInS5,
+  FivrRailAlwaysOn   = FivrRailInS0ix | FivrRailInSx
+} FIVR_RAIL_SX_STATE;
+
+typedef enum {
+  FivrRetentionActive = BIT0,
+  FivrNormActive      = BIT1,
+  FivrMinActive       = BIT2,
+  FivrMinRetention    = BIT3
+} FIVR_RAIL_SUPPORTED_VOLTAGE;
+
+/**
+  Structure for V1p05/Vnn VR rail configuration
+**/
+typedef struct {
+  /**
+    Mask to enable the usage of external VR rail in specific S0ix or Sx states
+    Use values from FIVR_RAIL_SX_STATE
+    The default is <b>FivrRailDisabled</b>.
+  **/
+  UINT32  EnabledStates   : 5;
+
+  /**
+    VR rail voltage value that will be used in S0i2/S0i3 states.
+    This value is given in 2.5mV increments (0=0mV, 1=2.5mV, 2=5mV...)
+    The default for Vnn is set to <b>420 - 1050 mV</b>.
+  **/
+  UINT32  Voltage         : 11;
+  /**
+    @deprecated
+    THIS POLICY IS DEPRECATED, PLEASE USE IccMaximum INSTEAD
+    VR rail Icc Max Value
+    Granularity of this setting is 1mA and maximal possible value is 500mA
+    The default is <b> 0mA </b>.
+  **/
+  UINT32  IccMax          : 8;
+
+  /**
+  This register holds the control hold off values to be used when
+  changing the rail control for external bypass value in us
+  **/
+  UINT32   CtrlRampTmr    : 8;
+
+  /**
+    Mask to set the supported configuration in VR rail.
+    Use values from FIVR_RAIL_SUPPORTED_VOLTAGE
+  **/
+  UINT32  SupportedVoltageStates   : 4;
+
+  /**
+    VR rail Icc Maximum Value
+    Granularity of this setting is 1mA and maximal possible value is 500mA
+    The default is <b> 0mA </b>.
+  **/
+  UINT32  IccMaximum                : 16;
+
+  UINT32  RsvdBits1                 : 12;
+
+} FIVR_EXT_RAIL_CONFIG;
+
+
+/**
+  Structure for VCCIN_AUX voltage rail configuration
+**/
+typedef struct {
+  /**
+  Transition time in microseconds from Low Current Mode Voltage to High Current Mode Voltage.
+  Voltage transition time required by motherboard voltage regulator when PCH changes
+  the VCCIN_AUX regulator set point from the low current mode voltage and high current mode voltage.
+  This field has 1us resolution.
+  When value is 0 PCH will not transition VCCIN_AUX to low current mode voltage.
+  The default is <b> 0xC </b>.
+  **/
+  UINT8  LowToHighCurModeVolTranTime;
+
+  /**
+  Transition time in microseconds from Retention Mode Voltage to High Current Mode Voltage.
+  Voltage transition time required by motherboard voltage regulator when PCH changes
+  the VCCIN_AUX regulator set point from the retention mode voltage to high current mode voltage.
+  This field has 1us resolution.
+  When value is 0 PCH will not transition VCCIN_AUX to retention voltage.
+  The default is <b> 0x36 </b>.
+  **/
+  UINT8  RetToHighCurModeVolTranTime;
+
+  /**
+  Transition time in microseconds from Retention Mode Voltage to Low Current Mode Voltage.
+  Voltage transition time required by motherboard voltage regulator when PCH changes
+  the VCCIN_AUX regulator set point from the retention mode voltage to low current mode voltage.
+  This field has 1us resolution.
+  When value is 0 PCH will not transition VCCIN_AUX to retention voltage.
+  The default is <b> 0x2B </b>.
+  **/
+  UINT8  RetToLowCurModeVolTranTime;
+  UINT8  RsvdByte1;
+  /**
+  Transition time in microseconds from Off (0V) to High Current Mode Voltage.
+  Voltage transition time required by motherboard voltage regulator when PCH changes
+  the VCCIN_AUX regulator set point from 0V to the high current mode voltage.
+  This field has 1us resolution.
+  0 = Transition to 0V is disabled
+  Setting this field to 0 sets VCCIN_AUX as a fixed rail that stays on
+  in all S0 & Sx power states after initial start up on G3 exit
+  The default is <b> 0x96 </b>.
+  **/
+  UINT32  OffToHighCurModeVolTranTime : 11;
+  UINT32  RsvdBits1                   : 21;
+} FIVR_VCCIN_AUX_CONFIG;
+
+/**
+  The PCH_FIVR_CONFIG block describes FIVR settings.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER      Header;  ///< Config Block Header
+  /**
+    External V1P05 VR rail configuration.
+  **/
+  FIVR_EXT_RAIL_CONFIG     ExtV1p05Rail;
+  /**
+    External Vnn VR rail configuration.
+  **/
+  FIVR_EXT_RAIL_CONFIG     ExtVnnRail;
+  /**
+    Additional External Vnn VR rail configuration that will get applied
+    in Sx entry SMI callback. Required only if External Vnn VR
+    needs different settings for Sx than those specified in ExtVnnRail.
+  **/
+  FIVR_EXT_RAIL_CONFIG     ExtVnnRailSx;
+  /**
+    VCCIN_AUX voltage rail configuration.
+  **/
+  FIVR_VCCIN_AUX_CONFIG    VccinAux;
+
+  /**
+    Enable/Disable FIVR Dynamic Power Management
+    Default is <b> 1 </b>.
+  **/
+  UINT32                   FivrDynPm : 1;
+  UINT32                   RsvdBits2 : 31;
+} PCH_FIVR_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _FIVR_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Gbe/GbeConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Gbe/GbeConfig.h
new file mode 100644
index 0000000000..cb9411f9e8
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Gbe/GbeConfig.h
@@ -0,0 +1,33 @@
+/** @file
+  Gigabit Ethernet policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _GBE_CONFIG_H_
+#define _GBE_CONFIG_H_
+
+#define GBE_CONFIG_REVISION 1
+extern EFI_GUID gGbeConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  PCH intergrated GBE controller configuration settings.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;  ///< Config Block Header
+  /**
+    Determines if enable PCH internal GBE, 0: Disable; <b>1: Enable</b>.
+    When Enable is changed (from disabled to enabled or from enabled to disabled),
+    it needs to set LAN Disable regsiter, which might be locked by FDSWL register.
+    So it's recommendated to issue a global reset when changing the status for PCH Internal LAN.
+  **/
+  UINT32  Enable          :  1;
+  UINT32  LtrEnable       :  1;  ///< <b>0: Disable</b>; 1: Enable LTR capabilty of PCH internal LAN.
+  UINT32  RsvdBits0       : 30;  ///< Reserved bits
+} GBE_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _GBE_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Gna/GnaConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Gna/GnaConfig.h
new file mode 100644
index 0000000000..87649253c6
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Gna/GnaConfig.h
@@ -0,0 +1,31 @@
+/** @file
+  Policy definition for GNA Config Block
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _GNA_CONFIG_H_
+#define _GNA_CONFIG_H_
+#pragma pack(push, 1)
+
+#define GNA_CONFIG_REVISION 1
+/**
+ GNA config block for configuring GNA.\n
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER         Header;                   ///< Offset 0-27 Config Block Header
+  /**
+  Offset 28:0
+  This policy enables the GNA Device (SA Device 8) if supported.
+  If FALSE, all other policies in this config block will be ignored.
+  <b>1=TRUE</b>;
+  0=FALSE.
+   **/
+  UINT32                      GnaEnable : 1;
+  UINT32                      RsvdBits0 : 31; ///< Offset 28:1 :Reserved for future use
+} GNA_CONFIG;
+#pragma pack(pop)
+
+#endif // _GNA_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Gpio/GpioDevConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Gpio/GpioDevConfig.h
new file mode 100644
index 0000000000..1a724f14da
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Gpio/GpioDevConfig.h
@@ -0,0 +1,37 @@
+/** @file
+  GPIO device policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _GPIO_DEV_CONFIG_H_
+#define _GPIO_DEV_CONFIG_H_
+
+extern EFI_GUID gGpioDxeConfigGuid;
+
+#define GPIO_DXE_CONFIG_REVISION 1
+
+#pragma pack (push,1)
+
+/**
+  This structure contains the DXE policies which are related to GPIO device.
+
+  <b>Revision 1:</b>
+  - Inital version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;          ///< Config Block Header
+  /**
+    If GPIO ACPI device is not used by OS it can be hidden. In such case
+    no other device exposed to the system can reference GPIO device in one
+    of its resources through GpioIo(..) or GpioInt(..) ACPI descriptors.
+    <b>0: Disable</b>; 1: Enable
+  **/
+  UINT32  HideGpioAcpiDevice    :  1;
+  UINT32  RsvdBits              : 31;    ///< Reserved bits
+
+} GPIO_DXE_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _GPIO_DEV_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Graphics/Gen12/GraphicsConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Graphics/Gen12/GraphicsConfig.h
new file mode 100644
index 0000000000..c3b134b830
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Graphics/Gen12/GraphicsConfig.h
@@ -0,0 +1,211 @@
+/** @file
+  Policy definition for Internal Graphics Config Block.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _GRAPHICS_CONFIG_H_
+#define _GRAPHICS_CONFIG_H_
+#pragma pack(push, 1)
+
+#define GRAPHICS_PEI_PREMEM_CONFIG_REVISION 3
+#define GRAPHICS_PEI_CONFIG_REVISION        7
+#define GRAPHICS_DXE_CONFIG_REVISION        1
+
+#define DDI_DEVICE_NUMBER   4
+#define MAX_BCLM_ENTRIES    20
+
+
+//
+// DDI defines
+//
+typedef enum {
+  DdiDisable       = 0x00,
+  DdiDdcEnable     = 0x01,
+} DDI_DDC_TBT_VAL;
+
+typedef enum {
+  DdiHpdDisable  = 0x00,
+  DdiHpdEnable   = 0x01,
+} DDI_HPD_VAL;
+
+typedef enum {
+  DdiPortDisabled = 0x00,
+  DdiPortEdp      = 0x01,
+  DdiPortMipiDsi  = 0x02,
+} DDI_PORT_SETTINGS;
+
+/**
+  This structure configures the Native GPIOs for DDI port per VBT settings.
+**/
+typedef struct {
+  UINT8 DdiPortAConfig; /// The Configuration of DDI port A, this settings must match VBT's settings. DdiPortDisabled - No LFP is connected on DdiPortA, <b>DdiPortEdp - Set DdiPortA to eDP</b>, DdiPortMipiDsi - Set DdiPortA to MIPI DSI
+  UINT8 DdiPortBConfig; /// The Configuration of DDI port B, this settings must match VBT's settings. DdiPortDisabled - No LFP is connected on DdiPortB, <b>DdiPortEdp - Set DdiPortB to eDP</b>, DdiPortMipiDsi - Set DdiPortB to MIPI DSI
+  UINT8 DdiPortAHpd;    /// The HPD setting of DDI Port A, this settings must match VBT's settings. <b>DdiHpdDisable - Disable HPD</b>, DdiHpdEnable - Enable HPD
+  UINT8 DdiPortBHpd;    /// The HPD setting of DDI Port B, this settings must match VBT's settings. DdiHpdDisable - Disable HPD, <b>DdiHpdEnable - Enable HPD</b>
+  UINT8 DdiPortCHpd;    /// The HPD setting of DDI Port C, this settings must match VBT's settings. <b>DdiHpdDisable - Disable HPD</b>, DdiHpdEnable - Enable HPD
+  UINT8 DdiPort1Hpd;    /// The HPD setting of DDI Port 1, this settings must match VBT's settings. <b>DdiHpdDisable - Disable HPD</b>, DdiHpdEnable - Enable HPD
+  UINT8 DdiPort2Hpd;    /// The HPD setting of DDI Port 2, this settings must match VBT's settings. <b>DdiHpdDisable - Disable HPD</b>, DdiHpdEnable - Enable HPD
+  UINT8 DdiPort3Hpd;    /// The HPD setting of DDI Port 3, this settings must match VBT's settings. <b>DdiHpdDisable - Disable HPD</b>, DdiHpdEnable - Enable HPD
+  UINT8 DdiPort4Hpd;    /// The HPD setting of DDI Port 4, this settings must match VBT's settings. <b>DdiHpdDisable - Disable HPD</b>, DdiHpdEnable - Enable HPD
+  UINT8 DdiPortADdc;    /// The DDC setting of DDI Port A, this settings must match VBT's settings. <b>DdiDisable - Disable DDC</b>, DdiDdcEnable - Enable DDC
+  UINT8 DdiPortBDdc;    /// The DDC setting of DDI Port B, this settings must match VBT's settings. DdiDisable - Disable DDC, <b>DdiDdcEnable - Enable DDC </b>
+  UINT8 DdiPortCDdc;    /// The DDC setting of DDI Port C, this settings must match VBT's settings. <b>DdiDisable - Disable DDC</b>, DdiDdcEnable - Enable DDC
+  UINT8 DdiPort1Ddc;    /// The DDC setting of DDI Port 1, this settings must match VBT's settings. <b>DdiDisable - Disable DDC</b>, DdiDdcEnable - Enable DDC
+  UINT8 DdiPort2Ddc;    /// The DDC setting of DDI Port 2, this settings must match VBT's settings. <b>DdiDisable - Disable DDC</b>, DdiDdcEnable - Enable DDC
+  UINT8 DdiPort3Ddc;    /// The DDC setting of DDI Port 3, this settings must match VBT's settings. <b>DdiDisable - Disable DDC</b>, DdiDdcEnable - Enable DDC
+  UINT8 DdiPort4Ddc;    /// The DDC setting of DDI Port 4, this settings must match VBT's settings. <b>DdiDisable - Disable DDC</b>, DdiDdcEnable - Enable DDC
+} DDI_CONFIGURATION;
+
+/**
+  This Configuration block is to configure GT related PreMem data/variables.\n
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Added DfdRestoreEnable.
+  <b>Revision 3</b>:
+  - Added DdiConfiguration.
+  <b>Revision 4</b>:
+  - Added GmAdr64 and made GmAdr obselete
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Offset 0-27 Config Block Header
+  /**
+    Offset 28
+    Selection of the primary display device: 0=iGFX, 1=PEG, 2=PCIe Graphics on PCH, <b>3=AUTO</b>, 4=Switchable Graphics\n
+    When AUTO mode selected, the priority of display devices is: PCIe Graphics on PCH > PEG > iGFX
+  **/
+  UINT8                PrimaryDisplay;
+  /**
+    Offset 29
+    Intel Gfx Support. It controls enabling/disabling iGfx device.
+    When AUTO mode selected, iGFX will be turned off when external graphics detected.
+    If FALSE, all other polices can be ignored.
+    <b>2 = AUTO</b>;
+    0 = FALSE;
+    1 = TRUE.
+  **/
+  UINT8                InternalGraphics;
+  /**
+    Offset 30
+    Pre-allocated memory for iGFX\n
+    0   = 0MB,1 or 247 = 32MB,\n
+    2   = 64MB,\n
+    240 = 4MB,     241 = 8MB,\n
+    242 = 12MB,    243 = 16MB,\n
+    244 = 20MB,    245 = 24MB,\n
+    246 = 28MB,    248 = 36MB,\n
+    249 = 40MB,    250 = 44MB,\n
+    251 = 48MB,    252 = 52MB,\n
+    253 = 56MB,<b> 254 = 60MB</b>,\n
+    <b>Note: enlarging pre-allocated memory for iGFX may need to reduce MmioSize because of 4GB boundary limitation</b>
+  **/
+  UINT16               IgdDvmt50PreAlloc;
+  UINT8                PanelPowerEnable;    ///< Offset 32 :<b>(Test)</b> Control for enabling/disabling VDD force bit (Required only for early enabling of eDP panel): 0=FALSE, <b>1=TRUE</b>
+  UINT8                ApertureSize;        ///< Offset 33 :Graphics aperture size (256MB is the recommended size as per BWG) : 0=128MB, <b>1=256MB</b>, 3=512MB, 7=1024MB, 15=2048MB.
+  UINT8                GtPsmiSupport;       ///< Offset 34 :PSMI support On/Off: <b>0=FALSE</b>, 1=TRUE
+  UINT8                PsmiRegionSize;      ///< Offset 35 :Psmi region size: <b>0=32MB</b>, 1=288MB, 2=544MB, 3=800MB, 4=1056MB
+  UINT8                DismSize;            ///< Offset 36 :DiSM Size for 2LM Sku: <b>0=0GB</b>, 1=1GB, 2=2GB, 3=3GB, 4=4GB, 5=5GB, 6=6GB, 7=7GB
+  UINT8                DfdRestoreEnable;    ///< Offset 37 :Display memory map programming for DFD Restore <b>0- Disable</b>, 1- Enable
+  UINT16               GttSize;             ///< Offset 38 :Selection of iGFX GTT Memory size: 1=2MB, 2=4MB, <b>3=8MB</b>
+  /**
+  Offset 40
+  Temp Address of System Agent GTTMMADR: Default is <b>0xAF000000</b>
+  **/
+  UINT32               GttMmAdr;
+  UINT32               GmAdr;               ///< Offset 44 Obsolete not to be used, use GmAdr64
+  DDI_CONFIGURATION    DdiConfiguration;    ///< Offset 48 DDI configuration, need to match with VBT settings.
+
+  UINT8                GtClosEnable;        ///< Offset 50 Gt ClOS
+  UINT8                Rsvd0[7];            ///< Offset 51 Reserved for 4 bytes of alignment
+  /**
+  Offset 58
+  Temp Address of System Agent GMADR: Default is <b>0xB0000000</b>
+  **/
+  UINT64               GmAdr64;
+} GRAPHICS_PEI_PREMEM_CONFIG;
+
+/**
+  This configuration block is to configure IGD related variables used in PostMem PEI.
+  If Intel Gfx Device is not supported, all policies can be ignored.
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Removed DfdRestoreEnable.
+  <b>Revision 3</b>:
+  - Removed DdiConfiguration.
+  <b>Revision 4</b>:
+  - Added new CdClock frequency
+  <b>Revision 5</b>:
+  - Added GT Chicket bits
+  <b>Revision 6</b>:
+  - Added LogoPixelHeight and LogoPixelWidth
+  <b>Revision 7</b>:
+  - Added SkipFspGop
+
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER  Header;               ///< Offset 0-27 Config Block Header
+  UINT8                RenderStandby;        ///< Offset 28 :<b>(Test)</b> This field is used to enable or disable RC6 (Render Standby): 0=FALSE, <b>1=TRUE</b>
+  UINT8                PmSupport;            ///< Offset 29 :<b>(Test)</b> IGD PM Support TRUE/FALSE: 0=FALSE, <b>1=TRUE</b>
+  /**
+    Offset 30
+    CdClock Frequency select\n
+    <b>0xFF = Auto. Max CdClock freq based on Reference Clk</b> \n
+     0: 192 Mhz, 1: 307.2 Mhz, 2: 312 Mhz, 3: 324 Mhz, 4: 326.4 Mhz, 5: 552 Mhz, 6: 556.8 Mhz, 7: 648 Mhz, 8: 652.8 Mhz
+
+  **/
+  UINT16               CdClock;
+  UINT8                PeiGraphicsPeimInit;  ///< Offset 32 : This policy is used to enable/disable Intel Gfx PEIM.<b>0- Disable</b>, 1- Enable
+  UINT8                CdynmaxClampEnable;   ///< Offset 33 : This policy is used to enable/disable CDynmax Clamping Feature (CCF) <b>1- Enable</b>, 0- Disable
+  UINT16               GtFreqMax;            ///< Offset 34 : <b>(Test)</b> Max GT frequency limited by user in multiples of 50MHz: Default value which indicates normal frequency is <b>0xFF</b>
+  UINT8                DisableTurboGt;       ///< Offset 36 : This policy is used to enable/disable DisableTurboGt <b>0- Disable</b>, 1- Enable
+  UINT8                SkipCdClockInit;      ///< Offset 37 : SKip full CD clock initialization. <b>0- Disable</b>, 1- Enable
+  UINT8                RC1pFreqEnable;       ///< Offset 38 : This policy is used to enable/disable RC1p Frequency. <b>0- Disable</b>, 1- Enable
+  UINT8                PavpEnable;           ///< Offset 39 :IGD PAVP TRUE/FALSE: 0=FALSE, <b>1=TRUE</b>
+  VOID*                LogoPtr;              ///< Offset 40 Address of Intel Gfx PEIM Logo to be displayed
+  UINT32               LogoSize;             ///< Offset 44 Intel Gfx PEIM Logo Size
+  VOID*                GraphicsConfigPtr;    ///< Offset 48 Address of the Graphics Configuration Table
+  VOID*                BltBufferAddress;     ///< Offset 52 Address of Blt buffer for PEIM Logo use
+  UINT32               BltBufferSize;        ///< Offset 56 The size for Blt Buffer, calculating by PixelWidth * PixelHeight * 4 bytes (the size of EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+  UINT8                ProgramGtChickenBits; ///< Offset 60 Program GT Chicket bits in GTTMMADR + 0xD00 BITS [3:1].
+  UINT8                SkipFspGop;           ///< Offset 61 This policy is used to skip PEIM GOP in FSP.<b>0- Use FSP provided GOP driver</b>, 1- Skip FSP provided GOP driver
+  UINT8                Rsvd1[2];             ///< Offset 62 Reserved for 4 bytes alignment
+  UINT32               LogoPixelHeight;      ///< Offset 64 Address of LogoPixelHeight for PEIM Logo use
+  UINT32               LogoPixelWidth;       ///< Offset 68 Address of LogoPixelWidth for PEIM Logo use
+} GRAPHICS_PEI_CONFIG;
+
+/**
+  This configuration block is to configure IGD related variables used in DXE.
+  If Intel Gfx Device is not supported or disabled, all policies will be ignored.
+  The data elements should be initialized by a Platform Module.\n
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Offset 0-27: Config Block Header
+  UINT32                Size;                     ///< Offset 28 - 31: This field gives the size of the GOP VBT Data buffer
+  EFI_PHYSICAL_ADDRESS  VbtAddress;               ///< Offset 32 - 39: This field points to the GOP VBT data buffer
+  UINT8                 PlatformConfig;           ///< Offset 40: This field gives the Platform Configuration Information (0=Platform is S0ix Capable for ULT SKUs only, <b>1=Platform is not S0ix Capable</b>, 2=Force Platform is S0ix Capable for All SKUs)
+  UINT8                 AlsEnable;                ///< Offset 41: Ambient Light Sensor Enable: <b>0=Disable</b>, 2=Enable
+  UINT8                 BacklightControlSupport;  ///< Offset 42: Backlight Control Support: 0=PWM Inverted, <b>2=PWM Normal</b>
+  UINT8                 IgdBootType;              ///< Offset 43: IGD Boot Type CMOS option: <b>0=Default</b>, 0x01=CRT, 0x04=EFP, 0x08=LFP, 0x20=EFP3, 0x40=EFP2, 0x80=LFP2
+  UINT32                IuerStatusVal;            ///< Offset 44 - 47: Offset 16 This field holds the current status of all the supported Ultrabook events (Intel(R) Ultrabook Event Status bits)
+  CHAR16                GopVersion[0x10];         ///< Offset 48 - 79:This field holds the GOP Driver Version. It is an Output Protocol and updated by the Silicon code
+  /**
+    Offset 80: IGD Panel Type CMOS option\n
+    <b>0=Default</b>, 1=640X480LVDS, 2=800X600LVDS, 3=1024X768LVDS, 4=1280X1024LVDS, 5=1400X1050LVDS1\n
+    6=1400X1050LVDS2, 7=1600X1200LVDS, 8=1280X768LVDS, 9=1680X1050LVDS, 10=1920X1200LVDS, 13=1600X900LVDS\n
+    14=1280X800LVDS, 15=1280X600LVDS, 16=2048X1536LVDS, 17=1366X768LVDS
+  **/
+  UINT8                 IgdPanelType;
+  UINT8                 IgdPanelScaling;          ///< Offset 81: IGD Panel Scaling: <b>0=AUTO</b>, 1=OFF, 6=Force scaling
+  UINT8                 IgdBlcConfig;             ///< Offset 82: Backlight Control Support: 0=PWM Inverted, <b>2=PWM Normal</b>
+  UINT8                 IgdDvmtMemSize;           ///< Offset 83: IGD DVMT Memory Size: 1=128MB, <b>2=256MB</b>, 3=MAX
+  UINT8                 GfxTurboIMON;             ///< Offset 84: IMON Current Value: 14=Minimal, <b>31=Maximum</b>
+  UINT8                 Reserved[3];              ///< Offset 85: Reserved for DWORD alignment.
+  UINT16                BCLM[MAX_BCLM_ENTRIES];   ///< Offset 88: IGD Backlight Brightness Level Duty cycle Mapping Table.
+} GRAPHICS_DXE_CONFIG;
+#pragma pack(pop)
+
+#endif // _GRAPHICS_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Hda/HdAudioConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Hda/HdAudioConfig.h
new file mode 100644
index 0000000000..a2e0a65e45
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Hda/HdAudioConfig.h
@@ -0,0 +1,227 @@
+/** @file
+  HDAUDIO policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _HDAUDIO_CONFIG_H_
+#define _HDAUDIO_CONFIG_H_
+
+#include <ConfigBlock.h>
+#include <PchLimits.h>
+
+#define HDAUDIO_PREMEM_CONFIG_REVISION 2
+#define HDAUDIO_CONFIG_REVISION 1
+#define HDAUDIO_DXE_CONFIG_REVISION 1
+
+extern EFI_GUID gHdAudioPreMemConfigGuid;
+extern EFI_GUID gHdAudioConfigGuid;
+extern EFI_GUID gHdAudioDxeConfigGuid;
+
+#pragma pack (push,1)
+
+///
+/// The PCH_HDAUDIO_CONFIG block describes the expected configuration of the Intel HD Audio feature.
+///
+
+#define HDAUDIO_VERB_TABLE_VIDDID(Vid,Did)                      (UINT32)((UINT16)Vid | ((UINT16)Did << 16))
+#define HDAUDIO_VERB_TABLE_RID_SDI_SIZE(Rid,Sdi,VerbTableSize)  (UINT32)((UINT8)Rid | ((UINT8)Sdi << 8) | ((UINT16)VerbTableSize << 16))
+#define HDAUDIO_VERB_TABLE_CMD_SIZE(VerbTable)                  ((sizeof (VerbTable) - sizeof (HDA_VERB_TABLE_HEADER)) / (sizeof (UINT32)))
+
+///
+/// Use this macro to create HDAUDIO_VERB_TABLE and populate size automatically
+///
+#define HDAUDIO_VERB_TABLE_INIT(Vid,Did,Rid,Sdi,...) \
+{ \
+  { Vid, Did, Rid, Sdi, (sizeof((UINT32[]){__VA_ARGS__})/sizeof(UINT32)) }, \
+  { __VA_ARGS__ } \
+}
+
+
+/**
+  Azalia verb table header
+  Every verb table should contain this defined header and followed by azalia verb commands.
+**/
+typedef struct {
+  UINT16  VendorId;             ///< Codec Vendor ID
+  UINT16  DeviceId;             ///< Codec Device ID
+  UINT8   RevisionId;           ///< Revision ID of the codec. 0xFF matches any revision.
+  UINT8   SdiNum;               ///< SDI number, 0xFF matches any SDI.
+  UINT16  DataDwords;           ///< Number of data DWORDs following the header.
+} HDA_VERB_TABLE_HEADER;
+
+#ifdef _MSC_VER
+//
+// Disable "zero-sized array in struct/union" extension warning.
+// Used for neater verb table definitions.
+//
+#pragma warning (push)
+#pragma warning (disable: 4200)
+#endif
+typedef struct  {
+  HDA_VERB_TABLE_HEADER  Header;
+  UINT32 Data[];
+} HDAUDIO_VERB_TABLE;
+#ifdef _MSC_VER
+#pragma warning (pop)
+#endif
+
+typedef struct {
+  UINT32   ClkA;            ///<  Pin mux configuration. Refer to GPIO_*_MUXING_DMIC*_CLKA_*
+  UINT32   ClkB;            ///<  Pin mux configuration. Refer to GPIO_*_MUXING_DMIC*_CLKB_*
+  UINT32   Data;            ///<  Pin mux configuration. Refer to GPIO_*_MUXING_DMIC*_DATA_*
+} HDA_DMIC_PIN_MUX;
+
+/**
+  HD Audio Link Policies
+**/
+typedef struct {
+  UINT32  Enable    :  1;  ///< HDA interface enable. When enabled related pins will be switched to native mode: <b>0: Disable</b>; 1: Enable.
+  UINT32  RsvdBits0 : 31;
+  UINT8   SdiEnable[PCH_MAX_HDA_SDI];  ///< HDA SDI signal enable. When enabled related SDI pins will be switched to appropriate native mode: <b>0: Disable</b>; 1: Enable
+  UINT8   Reserved[(4 - (PCH_MAX_HDA_SDI % 4)) % 4];  ///< Padding for SDI enable table.
+} HDA_LINK_HDA;
+
+/**
+  HD Audio DMIC Interface Policies
+**/
+typedef struct {
+  UINT32             Enable          :  1;  ///< HDA DMIC interface enable. When enabled related pins will be switched to native mode: <b>0: Disable</b>; 1: Enable.
+  UINT32             DmicClockSelect :  2;  ///< DMIC link clock select: <b>0: Both</b>, 1: ClkA, 2: ClkB; default is "Both"
+  UINT32             RsvdBits0       : 29;
+  HDA_DMIC_PIN_MUX   PinMux;          ///< Pin mux configuration.
+} HDA_LINK_DMIC;
+
+/**
+  HD Audio SSP Interface Policies
+**/
+typedef struct {
+  UINT32             Enable    :  1;  ///< HDA SSP interface enable. When enabled related pins will be switched to native mode: <b>0: Disable</b>; 1: Enable.
+  UINT32             RsvdBits0 : 31;
+} HDA_LINK_SSP;
+
+/**
+  HD Audio SNDW Interface Policies
+**/
+typedef struct {
+  UINT32             Enable    :  1;  ///< HDA SNDW interface enable. When enabled related pins will be switched to native mode: <b>0: Disable</b>; 1: Enable.
+  UINT32             RsvdBits0 : 31;
+} HDA_LINK_SNDW;
+
+
+/**
+  This structure contains the policies which are related to HD Audio device (cAVS).
+
+  <b>Revision 1:</b>
+  - Inital version.
+
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;          ///< Config Block Header
+  UINT32  Pme                   :  1;    ///< Azalia wake-on-ring, <b>0: Disable</b>; 1: Enable
+  UINT32  CodecSxWakeCapability :  1;    ///< Capability to detect wake initiated by a codec in Sx (eg by modem codec), <b>0: Disable</b>; 1: Enable
+  UINT32  HdAudioLinkFrequency  :  4;    ///< HDA-Link frequency (PCH_HDAUDIO_LINK_FREQUENCY enum): <b>2: 24MHz</b>, 1: 12MHz, 0: 6MHz
+  UINT32  RsvdBits0             : 26;    ///< Reserved bits 0
+  /**
+    Number of the verb table entry defined in VerbTablePtr.
+    Each entry points to a verb table which contains HDAUDIO_VERB_TABLE structure and verb command blocks.
+  **/
+  UINT8   VerbTableEntryNum;
+  UINT8   Rsvd0[3];                         ///< Reserved bytes, align to multiple 4
+  /**
+    Pointer to a verb table array.
+    This pointer points to 32bits address, and is only eligible and consumed in post mem phase.
+    Each entry points to a verb table which contains HDAUDIO_VERB_TABLE structure and verb command blocks.
+    The prototype of this is:
+    HDAUDIO_VERB_TABLE **VerbTablePtr;
+  **/
+  UINT32  VerbTablePtr;
+} HDAUDIO_CONFIG;
+
+/**
+  This structure contains the premem policies which are related to HD Audio device (cAVS).
+
+  <b>Revision 1:</b>
+  - Inital version.
+  <b>Revision 2:</b>
+  - Add DmicClockSelect
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;          ///< Config Block Header
+  UINT32  Enable                :  1;    ///< Intel HD Audio (Azalia) enablement: 0: Disable, <b>1: Enable</b>
+  UINT32  DspEnable             :  1;    ///< DSP enablement: 0: Disable; <b>1: Enable</b>
+  UINT32  VcType                :  1;    ///< Virtual Channel Type Select: <b>0: VC0</b>, 1: VC1
+  /**
+    Universal Audio Architecture compliance for DSP enabled system:
+    <b>0: Not-UAA Compliant (Intel SST driver supported only)</b>,
+       1: UAA Compliant (HDA Inbox driver or SST driver supported)
+  **/
+  UINT32  DspUaaCompliance      :  1;
+  UINT32  IDispLinkFrequency    :  4;    ///< iDisp-Link frequency (PCH_HDAUDIO_LINK_FREQUENCY enum): <b>4: 96MHz</b>, 3: 48MHz
+  UINT32  IDispLinkTmode        :  3;    ///< iDisp-Link T-Mode (PCH_HDAUDIO_IDISP_TMODE enum): <b>0: 2T</b>, 1: 1T, 2: 4T, 3: 8T, 4: 16T
+  UINT32  IDispCodecDisconnect  :  1;    ///< iDisplay Audio Codec disconnection, <b>0: Not disconnected, enumerable</b>; 1: Disconnected SDI, not enumerable
+  UINT32  PowerGatingSupported  :  1;    ///< Power Gating supported: <b>0: Not supported</b>, 1: Supported
+  UINT32  RsvdBits              : 19;    ///< Reserved bits 0
+
+  /**
+    Audio Link Mode configuration bitmask.
+    Allows to configure enablement of the following interfaces: HDA-Link, DMIC, SSP, SoundWire.
+  **/
+
+  HDA_LINK_HDA          AudioLinkHda;    ///< HDA-Link enablement: 0: Disable; <b>1: Enable</b>.
+  /**
+    DMIC link enablement: 0: Disable; <b>1: Enable</b>.
+    DMIC0  LKF: Muxed with SNDW2/SNDW4.
+  **/
+  HDA_LINK_DMIC         AudioLinkDmic [2];
+  /**
+    I2S/SSP link enablement: <b>0: Disable</b>; 1: Enable.
+    SSP0/1 LKF: Muxed with HDA.
+    @note Since the I2S/SSP2 pin set contains pads which are also used for CNVi purpose, enabling AudioLinkSsp2
+    is exclusive with CNVi is present.
+  **/
+  HDA_LINK_SSP          AudioLinkSsp  [PCH_MAX_HDA_SSP_LINK_NUM];
+  /**
+    SoundWire link enablement: <b>0: Disable</b>; 1: Enable.
+    SNDW2  LKF: Muxed with DMIC0/DMIC1.
+    SNDW3  LKF: Muxed with DMIC1.
+    SNDW4  LKF: Muxed with DMIC0.
+  **/
+  HDA_LINK_SNDW         AudioLinkSndw [PCH_MAX_HDA_SNDW_LINK_NUM];
+
+
+  UINT16  ResetWaitTimer;                   ///< <b>(Test)</b> The delay timer after Azalia reset, the value is number of microseconds. Default is <b>600</b>.
+  UINT8   Rsvd0[2];                         ///< Reserved bytes, align to multiple 4
+
+} HDAUDIO_PREMEM_CONFIG;
+
+typedef struct {
+  UINT32  AutonomousClockStop        :  1;    ///< SoundWire1 link autonomous clock stop capability: <b>0: Disable</b>; 1: Enable
+  UINT32  DataOnActiveIntervalSelect :  2;    ///< SoundWire1 link data on active interval select 0: 3 clock periods; <b>1: 4 clock periods</b>; 2: 5 clock periods; 3: 6 clock periods
+  UINT32  DataOnDelaySelect          :  1;    ///< SoundWire1 link data on delay select 0: 2 clock periods; <b>1: 3 clock periods</b>
+  UINT32  RsvdBits1                  : 28;    ///< Reserved bits 1
+} HDAUDIO_SNDW_CONFIG;
+
+/**
+  This structure contains the DXE policies which are related to HD Audio device (cAVS).
+  <b>Revision 1:</b>
+  - Inital version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER        Header;          ///< Config Block Header
+  /**
+    SNDW configuration for exposed via SNDW ACPI tables:
+  **/
+  HDAUDIO_SNDW_CONFIG        SndwConfig[PCH_MAX_HDA_SNDW_LINK_NUM];
+  /**
+    Bitmask of supported DSP features:
+    [BIT0] - WoV; [BIT1] - BT Sideband; [BIT2] - Codec VAD; [BIT5] - BT Intel HFP; [BIT6] - BT Intel A2DP
+    [BIT7] - DSP based speech pre-processing disabled; [BIT8] - 0: Intel WoV, 1: Windows Voice Activation
+    Default is <b>zero</b>.
+  **/
+  UINT32  DspFeatureMask;
+} HDAUDIO_DXE_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _HDAUDIO_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/HostBridge/HostBridgeConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/HostBridge/HostBridgeConfig.h
new file mode 100644
index 0000000000..67335be92e
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/HostBridge/HostBridgeConfig.h
@@ -0,0 +1,62 @@
+/** @file
+  Configurations for HostBridge
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _HOST_BRIDGE_CONFIG_H_
+#define _HOST_BRIDGE_CONFIG_H_
+
+#include <ConfigBlock.h>
+
+#define HOST_BRIDGE_PREMEM_CONFIG_REVISION 1
+#define HOST_BRIDGE_PEI_CONFIG_REVISION    1
+
+extern EFI_GUID gHostBridgePeiPreMemConfigGuid;
+extern EFI_GUID gHostBridgePeiConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  This configuration block describes HostBridge settings in PreMem.\n
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER  Header;               ///< Offset 0-27 Config Block Header
+  UINT32  MchBar;                            ///< Offset 28 Address of System Agent MCHBAR: <b>0xFEDC0000(TGL)/0xFED10000(RKL)/0xFEA80000(JSL)<b>
+  UINT32  DmiBar;                            ///< Offset 32 Address of System Agent DMIBAR: <b>0xFEDA0000</b>
+  UINT32  EpBar;                             ///< Offset 36 Address of System Agent EPBAR: <b>0xFEDA1000</b>
+  UINT32  GdxcBar;                           ///< Offset 40 Address of System Agent GDXCBAR: <b>0xFED84000</b>
+  UINT32  RegBar;                            ///< Offset 44 Address of System Agent REGBAR: <b>0xFB000000</b>
+  UINT32  EdramBar;                          ///< Offset 48 Address of System Agent EDRAMBAR: <b>0xFED80000</b>
+  /**
+    Offset 52 :
+    Size of reserved MMIO space for PCI devices\n
+    <b>0=AUTO</b>, 512=512MB, 768=768MB, 1024=1024MB, 1280=1280MB, 1536=1536MB, 1792=1792MB,
+    2048=2048MB, 2304=2304MB, 2560=2560MB, 2816=2816MB, 3072=3072MB\n
+    When AUTO mode selected, the MMIO size will be calculated by required MMIO size from PCIe devices detected.
+  **/
+  UINT32  MmioSize;
+  UINT32  MmioSizeAdjustment;                ///< Offset 56 Increase (given positive value) or Decrease (given negative value) the Reserved MMIO size when Dynamic Tolud/AUTO mode enabled (in MBs): <b>0=no adjustment</b>
+  UINT8   EnableAbove4GBMmio;                ///< Offset 60 Enable/disable above 4GB MMIO resource support: 0=Disable, <b>1=Enable</b>
+  UINT8   Reserved[3];                       ///< Offset 61 Reserved for future use.
+} HOST_BRIDGE_PREMEM_CONFIG;
+
+
+/**
+  This configuration block describes HostBridge settings in Post-Mem.\n
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER  Header;               ///< Offset 0-27 Config Block Header
+  UINT8  Device4Enable;                      ///< Offser 28 :This policy is used to control enable or disable System Agent Thermal device (0,4,0). <b>0=FALSE</b>, 1=TRUE.
+  UINT8  ChapDeviceEnable;                   ///< Offset 29 :<b>(Test)</b>This policy is used to control enable or disable System Agent Chap device (0,7,0). <b>0=FALSE</b>, 1=TRUE.
+  UINT8  SkipPamLock;                        ///< Offset 30 :To skip PAM register locking. @note It is still recommended to set PCI Config space B0: D0: F0: Offset 80h[0]=1 in platform code even Silicon code skipped this.\n <b>0=All PAM registers will be locked in Silicon code</b>, 1=Skip lock PAM registers in Silicon code.
+  UINT8  EdramTestMode;                      ///< Offset 28 :EDRAM Test Mode. For EDRAM stepping - 0- EDRAM SW Disable, 1- EDRAM SW Enable, <b> 2- EDRAM HW Mode</b>
+} HOST_BRIDGE_PEI_CONFIG;
+
+#pragma pack (pop)
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/HybridGraphics/HybridGraphicsConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/HybridGraphics/HybridGraphicsConfig.h
new file mode 100644
index 0000000000..3f420aed48
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/HybridGraphics/HybridGraphicsConfig.h
@@ -0,0 +1,66 @@
+/** @file
+  Hybrid Graphics policy definitions
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _HYBRID_GRAPHICS_CONFIG_H_
+#define _HYBRID_GRAPHICS_CONFIG_H_
+
+#define HYBRID_GRAPHICS_CONFIG_REVISION 2
+
+#pragma pack(push, 1)
+///
+/// GPIO Support
+///
+typedef enum {
+  NotSupported = 0,
+  PchGpio,
+  I2CGpio,
+} GPIO_SUPPORT;
+
+///
+/// CPU PCIe GPIO Data Structure
+///
+typedef struct {
+  UINT8   ExpanderNo; ///< Offset 0 Expander No For I2C based GPIO
+  BOOLEAN Active;     ///< Offset 1 0=Active Low; 1=Active High
+  UINT8   Rsvd0[2];   ///< Offset 2 Reserved
+  UINT32  GpioNo;     ///< Offset 4 GPIO pad
+} CPU_PCIE_GPIO_INFO;
+
+/**
+ CPU PCIE RTD3 GPIO Data Structure
+**/
+typedef struct {
+  CPU_PCIE_GPIO_INFO  HoldRst;      ///< Offset 0 This field contain PCIe HLD RESET GPIO value and level information
+  CPU_PCIE_GPIO_INFO  PwrEnable;    ///< Offset 8 This field contain PCIe PWR Enable GPIO value and level information
+  UINT32              WakeGpioNo;   ///< Offset 16 This field contain PCIe RTD3 Device Wake GPIO Number
+  UINT8               GpioSupport;  ///< Offset 20 Depends on board design the GPIO configuration may be different: <b>0=Not Supported</b>, 1=PCH Based, 2=I2C based
+  UINT8               Rsvd0[3];     ///< Offset 21
+} CPU_PCIE_RTD3_GPIO;
+
+/**
+  This Configuration block configures CPU PCI Express 0/1/2 RTD3 GPIOs & Root Port.
+  Hybrid Gfx uses the same GPIOs & Root port as PCI Express 0/1/2 RTD3.
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Add HgSlot Policy: PEG or PCH Slot Slection for Hybrid Graphics
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER Header;                ///< Offset 0-27 Config Block Header
+  CPU_PCIE_RTD3_GPIO  CpuPcie0Rtd3Gpio;      ///< Offset 28 RTD3 GPIOs used for PCIe
+  UINT8               RootPortIndex;         ///< Offset 52 Root Port Index number used for HG
+  UINT8               HgMode;                ///< Offset 53 HgMode: <b>0=Disabled</b>, 1=HG Muxed, 2=HG Muxless, 3=PEG
+  UINT16              HgSubSystemId;         ///< Offset 54 Hybrid Graphics Subsystem ID: <b>2212</b>
+  UINT16              HgDelayAfterPwrEn;     ///< Offset 56 Dgpu Delay after Power enable using Setup option: 0=Minimal, 1000=Maximum, <b>300=300 microseconds</b>
+  UINT16              HgDelayAfterHoldReset; ///< Offset 58 Dgpu Delay after Hold Reset using Setup option: 0=Minimal, 1000=Maximum, <b>100=100 microseconds</b>
+  CPU_PCIE_RTD3_GPIO  CpuPcie1Rtd3Gpio;      ///< Offset 60 RTD3 GPIOs used for PCIe
+  CPU_PCIE_RTD3_GPIO  CpuPcie2Rtd3Gpio;      ///< Offset 84 RTD3 GPIOs used for PCIe
+  CPU_PCIE_RTD3_GPIO  CpuPcie3Rtd3Gpio;      ///< Offset 108 RTD3 GPIOs used for PCIe
+  UINT8               HgSlot;                ///< Offset 132 Slot selection between PEG and PCH
+  UINT8               Rsvd0[3];              ///< Offset 133 Reserved Bytes
+} HYBRID_GRAPHICS_CONFIG;
+#pragma pack(pop)
+#endif // _HYBRID_GRAPHICS_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/HybridStorage/HybridStorageConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/HybridStorage/HybridStorageConfig.h
new file mode 100644
index 0000000000..705fe43751
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/HybridStorage/HybridStorageConfig.h
@@ -0,0 +1,36 @@
+/** @file
+  Hybrid Storage policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _HYBRID_STORAGE_CONFIG_H_
+#define _HYBRID_STORAGE_CONFIG_H_
+
+#include <ConfigBlock.h>
+
+#define HYBRID_STORAGE_CONFIG_REVISION 1
+
+extern EFI_GUID gHybridStorageConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  The HYBRID_STORAGE_CONFIG block describes the expected configuration for Hybrid Storage device
+
+  <b>Revision 1</b>:
+  - Init version
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  /**
+    Hybrid Storage Mode
+    <b>0: Disable</b>, 1: Enable Dynamic Configuration
+  **/
+  UINT8    HybridStorageMode;
+  UINT8    RsvdBytes[3];
+} HYBRID_STORAGE_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _HYBRID_STORAGE_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Ieh/IehConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Ieh/IehConfig.h
new file mode 100644
index 0000000000..a9275152f5
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Ieh/IehConfig.h
@@ -0,0 +1,34 @@
+/** @file
+  Integrated Error Handler policy.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _IEH_CONFIG_H_
+#define _IEH_CONFIG_H_
+
+#define IEH_MODE_BYPASS 0
+#define IEH_MODE_ENABLE 1
+
+#define IEH_CONFIG_REVISION 1
+extern EFI_GUID gIehConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  The IEH_CONFIG block describes the expected configuration of the PCH
+  Integrated Error Handler.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER  Header;           ///< Config Block Header
+  /**
+    IEH mode <b>0: Bypass Mode</b>; 1: Enable
+  **/
+  UINT32    Mode            :  1;
+  UINT32    RsvdBits0       : 31;       ///< Reserved bits
+} IEH_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _IEH_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Ish/IshConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Ish/IshConfig.h
new file mode 100644
index 0000000000..75a11e3052
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Ish/IshConfig.h
@@ -0,0 +1,134 @@
+/** @file
+  ISH policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _ISH_CONFIG_H_
+#define _ISH_CONFIG_H_
+
+#define ISH_PREMEM_CONFIG_REVISION 1
+#define ISH_CONFIG_REVISION 1
+extern EFI_GUID gIshPreMemConfigGuid;
+extern EFI_GUID gIshConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  ISH GPIO settings
+**/
+typedef struct {
+  /**
+    GPIO signals pin muxing settings. If signal can be enable only on a single pin
+    then this parameter should be set to 0. Refer to GPIO_*_MUXING_ISH_*x_* in GpioPins*.h
+    for supported settings on a given platform
+  **/
+  UINT32   PinMux;                      ///< GPIO Pin mux configuration. Refer to GPIO_*_MUXING_ISH_*x_MOSI_*
+  /**
+    GPIO Pads Internal Termination.
+    For more information please see Platform Design Guide.
+    Check GPIO_ELECTRICAL_CONFIG for reference
+  **/
+  UINT32   PadTermination;
+} ISH_GPIO_CONFIG;
+
+/**
+  SPI signals settings.
+**/
+typedef struct {
+  ISH_GPIO_CONFIG   Mosi;                        ///< MOSI Pin configuration.
+  ISH_GPIO_CONFIG   Miso;                        ///< MISO Pin configuration.
+  ISH_GPIO_CONFIG   Clk;                         ///< CLK  Pin configuration.
+  ISH_GPIO_CONFIG   Cs[PCH_MAX_ISH_SPI_CS_PINS]; ///< CS   Pin configuration.
+} ISH_SPI_PIN_CONFIG;
+
+
+/**
+  UART signals settings.
+**/
+typedef struct {
+  ISH_GPIO_CONFIG   Rx;    ///< RXD Pin configuration.
+  ISH_GPIO_CONFIG   Tx;    ///< TXD Pin configuration.
+  ISH_GPIO_CONFIG   Rts;   ///< RTS Pin configuration.
+  ISH_GPIO_CONFIG   Cts;   ///< CTS Pin configuration.
+} ISH_UART_PIN_CONFIG;
+
+
+/**
+  I2C signals settings.
+**/
+typedef struct {
+  ISH_GPIO_CONFIG   Sda;    ///< SDA Pin configuration.
+  ISH_GPIO_CONFIG   Scl;    ///< SCL Pin configuration.
+} ISH_I2C_PIN_CONFIG;
+
+
+/**
+  Struct contains GPIO pins assigned and signal settings of SPI
+**/
+typedef struct {
+  UINT8               Enable;                            ///< ISH SPI GPIO pins assigned: <b>0: False</b> 1: True
+  UINT8               CsEnable[PCH_MAX_ISH_SPI_CS_PINS]; ///< ISH SPI CS pins assigned: <b>0: False</b> 1: True
+  UINT16              RsvdField0;                        ///< Reserved field
+  ISH_SPI_PIN_CONFIG  PinConfig;
+} ISH_SPI;
+
+
+/**
+  Struct contains GPIO pins assigned and signal settings of UART
+**/
+typedef struct {
+  UINT32              Enable      :  1;   ///< ISH UART GPIO pins assigned: <b>0: False</b> 1: True
+  UINT32              RsvdBits0   : 31;   ///< Reserved Bits
+  ISH_UART_PIN_CONFIG PinConfig;
+} ISH_UART;
+
+/**
+  Struct contains GPIO pins assigned and signal settings of I2C
+**/
+typedef struct {
+  UINT32              Enable      :  1;   ///< ISH I2C GPIO pins assigned: <b>0: False</b> 1: True
+  UINT32              RsvdBits0   : 31;   ///< Reserved Bits
+  ISH_I2C_PIN_CONFIG  PinConfig;
+} ISH_I2C;
+
+/**
+  Struct contains GPIO pins assigned and signal settings of GP
+**/
+typedef struct {
+  UINT32           Enable      :  1;   ///< ISH GP GPIO pins assigned: <b>0: False</b> 1: True
+  UINT32           RsvdBits0   : 31;   ///< Reserved Bits
+  ISH_GPIO_CONFIG  PinConfig;
+} ISH_GP;
+
+///
+/// The ISH_CONFIG block describes Integrated Sensor Hub device.
+///
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;               ///< Config Block Header
+  ISH_SPI  Spi[PCH_MAX_ISH_SPI_CONTROLLERS];
+  ISH_UART Uart[PCH_MAX_ISH_UART_CONTROLLERS];
+  ISH_I2C  I2c[PCH_MAX_ISH_I2C_CONTROLLERS];
+  ISH_GP   Gp[PCH_MAX_ISH_GP_PINS];
+
+  UINT32   PdtUnlock            :  1;         ///< ISH PDT Unlock Msg: <b>0: False</b> 1: True
+  UINT32   RsvdBits0            : 31;         ///< Reserved Bits
+
+} ISH_CONFIG;
+
+///
+/// Premem Policy for Integrated Sensor Hub device.
+///
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;     ///< Config Block Header
+  /**
+    ISH Controler 0: Disable; <b>1: Enable</b>.
+    For Desktop sku, the ISH POR should be disabled. <b> 0:Disable </b>.
+  **/
+  UINT32    Enable          :  1;
+  UINT32    RsvdBits0       : 31;   ///< Reserved Bits
+} ISH_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _ISH_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Itss/InterruptConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Itss/InterruptConfig.h
new file mode 100644
index 0000000000..7f6fa8675b
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Itss/InterruptConfig.h
@@ -0,0 +1,58 @@
+/** @file
+  Interrupt policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _INTERRUPT_CONFIG_H_
+#define _INTERRUPT_CONFIG_H_
+
+#define INTERRUPT_CONFIG_REVISION 1
+extern EFI_GUID gInterruptConfigGuid;
+
+#pragma pack (push,1)
+
+//
+// --------------------- Interrupts Config ------------------------------
+//
+typedef enum {
+  PchNoInt,        ///< No Interrupt Pin
+  PchIntA,
+  PchIntB,
+  PchIntC,
+  PchIntD
+} PCH_INT_PIN;
+
+///
+/// The PCH_DEVICE_INTERRUPT_CONFIG block describes interrupt pin, IRQ and interrupt mode for PCH device.
+///
+typedef struct {
+  UINT8        Device;                  ///< Device number
+  UINT8        Function;                ///< Device function
+  UINT8        IntX;                    ///< Interrupt pin: INTA-INTD (see PCH_INT_PIN)
+  UINT8        Irq;                     ///< IRQ to be set for device.
+} PCH_DEVICE_INTERRUPT_CONFIG;
+
+#define PCH_MAX_DEVICE_INTERRUPT_CONFIG 128       ///< Number of all PCH devices
+#define PCH_MAX_PXRC_CONFIG               8       ///< Number of PXRC registers in ITSS
+#define PCH_MAX_ITSS_IPC_REGS             4       ///< Number of IPC registers in ITSS
+#define PCH_MAX_ITSS_IRQ_NUM            120       ///< Maximum number of IRQs
+
+
+///
+/// The PCH_INTERRUPT_CONFIG block describes interrupt settings for PCH.
+///
+typedef struct {
+  CONFIG_BLOCK_HEADER          Header;                                          ///< Config Block Header
+  UINT8                        NumOfDevIntConfig;                               ///< Number of entries in DevIntConfig table
+  UINT8                        Rsvd0[3];                                        ///< Reserved bytes, align to multiple 4.
+  PCH_DEVICE_INTERRUPT_CONFIG  DevIntConfig[PCH_MAX_DEVICE_INTERRUPT_CONFIG];   ///< Array which stores PCH devices interrupts settings
+  UINT8                        GpioIrqRoute;                                    ///< Interrupt routing for GPIO. Default is <b>14</b>.
+  UINT8                        SciIrqSelect;                                    ///< Interrupt select for SCI. Default is <b>9</b>.
+  UINT8                        TcoIrqSelect;                                    ///< Interrupt select for TCO. Default is <b>9</b>.
+  UINT8                        TcoIrqEnable;                                    ///< Enable IRQ generation for TCO. <b>0: Disable</b>; 1: Enable.
+} PCH_INTERRUPT_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _INTERRUPT_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Itss/IoApicConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Itss/IoApicConfig.h
new file mode 100644
index 0000000000..726a27f7a1
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Itss/IoApicConfig.h
@@ -0,0 +1,60 @@
+/** @file
+  IoApic policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _IOAPIC_CONFIG_H_
+#define _IOAPIC_CONFIG_H_
+
+#define IOAPIC_CONFIG_REVISION 1
+extern EFI_GUID gIoApicConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  The PCH_IOAPIC_CONFIG block describes the expected configuration of the PCH
+  IO APIC, it's optional and PCH code would ignore it if the BdfValid bit is
+  not TRUE. Bus:device:function fields will be programmed to the register
+  P2SB IBDF(P2SB PCI offset R6Ch-6Dh), it's using for the following purpose:
+  As the Requester ID when initiating Interrupt Messages to the processor.
+  As the Completer ID when responding to the reads targeting the IOxAPI's
+  Memory-Mapped I/O registers.
+  This field defaults to Bus 0: Device 31: Function 0 after reset. BIOS can
+  program this field to provide a unique Bus:Device:Function number for the
+  internal IOxAPIC.
+  The address resource range of IOAPIC must be reserved in E820 and ACPI as
+  system resource.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header
+  UINT32  IoApicEntry24_119     :  1;   ///< 0: Disable; <b>1: Enable</b> IOAPIC Entry 24-119
+  /**
+    Enable 8254 Static Clock Gating during early POST time. 0: Disable, <b>1: Enable</b>
+    Setting 8254CGE is required to support SLP_S0.
+    Enable this if 8254 timer is not used.
+    However, set 8254CGE=1 in POST time might fail to boot legacy OS using 8254 timer.
+    Make sure it is disabled to support legacy OS using 8254 timer.
+    @note:
+    For some OS environment that it needs to set 8254CGE in late state it should
+    set this policy to FALSE and use ItssSet8254ClockGateState  (TRUE) in SMM later.
+    This is also required during S3 resume.
+    To avoid SMI requirement in S3 reusme path, it can enable the Enable8254ClockGatingOnS3
+    and RC will do 8254 CGE programming in PEI during S3 resume with BOOT_SAI.
+  **/
+  UINT32  Enable8254ClockGating :  1;
+  /**
+    Enable 8254 Static Clock Gating on S3 resume path. 0: Disable, <b>1: Enable</b>
+    This is only applicable when Enable8254ClockGating is disabled.
+    If Enable8254ClockGating is enabled, RC will do the 8254 CGE programming on
+    S3 resume path as well.
+  **/
+  UINT32  Enable8254ClockGatingOnS3 :  1;
+  UINT32  RsvdBits1             : 29;   ///< Reserved bits
+  UINT8   IoApicId;                     ///< This member determines IOAPIC ID. Default is <b>0x02</b>.
+  UINT8   Rsvd0[3];                     ///< Reserved bytes
+} PCH_IOAPIC_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _IOAPIC_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Me/MePeiConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Me/MePeiConfig.h
new file mode 100644
index 0000000000..82786501f0
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Me/MePeiConfig.h
@@ -0,0 +1,117 @@
+/** @file
+  ME config block for PEI phase
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _ME_PEI_CONFIG_H_
+#define _ME_PEI_CONFIG_H_
+
+#define ME_PEI_PREMEM_CONFIG_REVISION 2
+extern EFI_GUID gMePeiPreMemConfigGuid;
+
+#ifndef PLATFORM_POR
+#define PLATFORM_POR  0
+#endif
+#ifndef FORCE_ENABLE
+#define FORCE_ENABLE  1
+#endif
+#ifndef FORCE_DISABLE
+#define FORCE_DISABLE 2
+#endif
+
+#pragma pack (push,1)
+
+/**
+  ME Pei Pre-Memory Configuration Structure.
+
+  <b>Revision 1:</b>
+  - Initial version.
+  <b>Revision 2:</b>
+  - Add SkipCpuReplacementCheck Option.
+  <b>Revision 3:</b>
+  - Deprecate SendDidMsg.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                 ///< Config Block Header
+  UINT32 HeciTimeouts                     : 1;  ///< 0: Disable; <b>1: Enable</b> - HECI Send/Receive Timeouts.
+  /**
+    <b>(Test)</b>
+    <b>0: Disabled</b>
+       1: ME DID init stat 0 - Success
+       2: ME DID init stat 1 - No Memory in Channels
+       3: ME DID init stat 2 - Memory Init Error
+  **/
+  UINT32 DidInitStat                      : 2;
+  /**
+    <b>(Test)</b>
+    <b>0: Set to 0 to enable polling for CPU replacement</b>
+       1: Set to 1 will disable polling for CPU replacement
+  **/
+  UINT32 DisableCpuReplacedPolling        : 1;
+  UINT32 SendDidMsg                       : 1;  ///< <b>(Deprecated)</b> 0: Disable; <b>1: Enable</b> - Enable/Disable to send DID message.
+  /**
+    <b>(Test)</b>
+    <b>0: ME BIOS will check each messages before sending</b>
+       1: ME BIOS always sends messages without checking
+  **/
+  UINT32 DisableMessageCheck              : 1;
+  /**
+    <b>(Test)</b>
+    The SkipMbpHob policy determines whether ME BIOS Payload data will be requested during boot
+    in a MBP message. If set to 1, BIOS will send the MBP message with SkipMbp flag
+    set causing CSME to respond with MKHI header only and no MBP data
+    <b>0: ME BIOS will keep MBP and create HOB for MBP data</b>
+       1: ME BIOS will skip MBP data
+  **/
+  UINT32 SkipMbpHob                       : 1;
+  UINT32 HeciCommunication2               : 1;  ///< <b>(Test)</b> <b>0: Disable</b>; 1: Enable - Enable/Disable HECI2.
+  UINT32 KtDeviceEnable                   : 1;  ///< <b>(Test)</b> 0: Disable; <b>1: Enable</b> - Enable/Disable Kt Device.
+  UINT32 SkipCpuReplacementCheck          : 1;  ///< <b>(Test)</b> <b>0: Disable</b>; 1: Enable - Enable/Disable to skip CPU replacement check.
+  UINT32 RsvdBits                         : 22; ///< Reserved for future use & Config block alignment
+  UINT32 Heci1BarAddress;                       ///< HECI1 BAR address.
+  UINT32 Heci2BarAddress;                       ///< HECI2 BAR address.
+  UINT32 Heci3BarAddress;                       ///< HECI3 BAR address.
+} ME_PEI_PREMEM_CONFIG;
+#pragma pack (pop)
+
+
+#define ME_PEI_CONFIG_REVISION 3
+extern EFI_GUID gMePeiConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  ME Pei Post-Memory Configuration Structure.
+
+  <b>Revision 1:</b>
+  - Initial version.
+  <b>Revision 2</b>:
+  - Deprecated Heci3Enabled.
+  <b>Revision 3</b>
+  - Added EnforceEDebugMode.
+**/
+
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                 ///< Config Block Header
+
+  UINT32 EndOfPostMessage                 : 2;  ///< 0: Disabled; 1: Send in PEI; <b>2: Send in DXE</b> - Send EOP at specific phase.
+  UINT32 Heci3Enabled                     : 1;  ///< @deprecated
+  UINT32 DisableD0I3SettingForHeci        : 1;  ///< <b>(Test)</b> <b>0: Disable</b>; 1: Enable - Enable/Disable D0i3 for HECI.
+  /**
+    Enable/Disable Me Unconfig On Rtc Clear. If enabled, BIOS will send MeUnconfigOnRtcClearDisable Msg with parameter 0.
+    It will cause ME to unconfig if RTC is cleared.
+    -    0: Disable
+    - <b>1: Enable</b>
+    -    2: Cmos is clear, status unkonwn
+    -    3: Reserved
+  **/
+  UINT32 MeUnconfigOnRtcClear             : 2;
+  UINT32 MctpBroadcastCycle               : 1;   ///< <b>(Test)</b> <b>0: Disable</b>; 1: Enable - Program registers for MCTP Cycle.
+  UINT32 EnforceEDebugMode                : 1;   ///< <b>0: Disable</b>; 1: Enable - Enforces ME to enter Enhanced Debug Mode
+  UINT32 RsvdBits                         : 24;  ///< Reserved for future use & Config block alignment
+} ME_PEI_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _ME_PEI_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Memory/Ver2/MemoryConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Memory/Ver2/MemoryConfig.h
new file mode 100644
index 0000000000..17c0a10eee
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Memory/Ver2/MemoryConfig.h
@@ -0,0 +1,478 @@
+/** @file
+  Policy definition of Memory Config Block
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _MEMORY_CONFIG_H_
+#define _MEMORY_CONFIG_H_
+
+
+#pragma pack(push, 1)
+
+// MEMORY_CONFIG_REVISION 3 adds DDR5 PDA Enumeration training within MEMORY_CONFIGURATION
+// MEMORY_CONFIG_REVISION 4 adds LPDDR4 Command Mirroring within MEMORY_CONFIGURATION
+// MEMORY_CONFIG_REVISION 5 adds CpuBclkSpread option within MEMORY_CONFIGURATION
+// MEMORY_CONFIG_REVISION 6 adds McParity option within MEMORY_CONFIGURATION
+// MEMORY_CONFIG_REVISION 7 adds VddqVoltageOverride option within MEMORY_CONFIGURATION
+// MEMORY_CONFIG_REVISION 8 adds ExtendedBankHashing option within MEMORY_CONFIGURATION
+// MEMORY_CONFIG_REVISION 9 adds IbeccErrorInj option within MEMORY_CONFIGURATION
+#define MEMORY_CONFIG_REVISION 9
+///
+/// MEMORY_CONFIG interface definitions
+///
+#define MRC_MAX_RCOMP_TARGETS  5
+///
+/// Memory SubSystem Definitions
+///
+#define MEM_CFG_MAX_CONTROLLERS          2
+#define MEM_CFG_MAX_CHANNELS             4
+#define MEM_CFG_MAX_CHANNEL_SHARE_REGS   2
+#define MEM_CFG_MAX_DIMMS                2
+#define MEM_CFG_MAX_RANKS_PER_DIMM       2
+#define MEM_CFG_NUM_BYTES_MAPPED         2
+#define MEM_CFG_MAX_SPD_SIZE             1024
+#define MEM_CFG_MAX_SOCKETS              (MEM_CFG_MAX_CONTROLLERS * MEM_CFG_MAX_CHANNELS * MEM_CFG_MAX_DIMMS)
+#define MEM_CFG_MAX_ROWS                 (MEM_CFG_MAX_RANKS_PER_DIMM * MEM_CFG_MAX_SOCKETS)
+#ifndef MEM_MAX_SAGV_POINTS
+#define MEM_MAX_SAGV_POINTS                  4
+#endif
+#define MEM_MAX_IBECC_REGIONS                8
+///
+/// SMRAM Memory Range
+///
+#define PEI_MR_SMRAM_ABSEG_MASK     0x01
+#define PEI_MR_SMRAM_HSEG_MASK      0x02
+
+///
+/// SA SPD profile selections.
+///
+typedef enum {
+  Default,             ///< 0, Default SPD
+  UserDefined,         ///< 1, User Defined profile
+  XMPProfile1,         ///< 2, XMP Profile 1
+  XMPProfile2,         ///< 3, XMP Profile 2
+  XMPProfileMax = 0xFF ///< Ensures SA_SPD is UINT8
+} SA_SPD;
+
+///
+/// Define the boot modes used by the SPD read function.
+///
+typedef enum {
+  SpdCold,       ///< Cold boot
+  SpdWarm,       ///< Warm boot
+  SpdS3,         ///< S3 resume
+  SpdFast,       ///< Fast boot
+  SpdBootModeMax ///< Delimiter
+} SPD_BOOT_MODE;
+
+/**
+  SPD Data Buffer
+**/
+typedef struct {
+  UINT8 SpdData[MEM_CFG_MAX_CONTROLLERS][MEM_CFG_MAX_CHANNELS][MEM_CFG_MAX_DIMMS][MEM_CFG_MAX_SPD_SIZE];  ///< SpdData
+//Next Field Offset 2048
+} SPD_DATA_BUFFER;
+
+/**
+  DqDqs Mapping
+**/
+typedef struct {
+  UINT8 DqsMapCpu2Dram[MEM_CFG_MAX_CONTROLLERS][MEM_CFG_MAX_CHANNELS][MEM_CFG_NUM_BYTES_MAPPED];  ///< DqsMapCpu2Dram
+  UINT8 DqMapCpu2Dram[MEM_CFG_MAX_CONTROLLERS][MEM_CFG_MAX_CHANNELS][MEM_CFG_NUM_BYTES_MAPPED][8];  ///< DqMapCpu2Dram
+//Next Field Offset 16
+} SA_MEMORY_DQDQS_MAPPING;
+
+/**
+  Rcomp Policies
+**/
+typedef struct {
+  UINT16  RcompResistor;                      ///< Offset 0: Reference RCOMP resistors on motherboard ~ 100 ohms
+  UINT16  RcompTarget[MRC_MAX_RCOMP_TARGETS]; ///< Offset 1: RCOMP target values for DqOdt, DqDrv, CmdDrv, CtlDrv, ClkDrv
+//Next Field Offset 16
+} SA_MEMORY_RCOMP;
+
+/**
+  SPD Offset Table
+**/
+typedef struct {
+  UINT16 Start;           ///< Offset 0
+  UINT16 End;             ///< Offset 2
+  UINT8  BootMode;        ///< Offset 4
+  UINT8  Reserved3[3];    ///< Offset 5 Reserved for future use
+} SPD_OFFSET_TABLE;
+
+///
+/// SA memory address decode.
+///
+typedef struct
+{
+  UINT8  Controller; ///< Offset 0 Zero based Controller number
+  UINT8  Channel;    ///< Offset 1 Zero based Channel number
+  UINT8  Dimm;       ///< Offset 2 Zero based DIMM number
+  UINT8  Rank;       ///< Offset 3 Zero based Rank number
+  UINT8  BankGroup;  ///< Offset 4 Zero based Bank Group number
+  UINT8  Bank;       ///< Offset 5 Zero based Bank number
+  UINT16 Cas;        ///< Offset 6 Zero based CAS number
+  UINT32 Ras;        ///< Offset 8 Zero based RAS number
+} SA_ADDRESS_DECODE;
+
+typedef UINT8      (EFIAPI * SA_IO_READ_8)               (UINTN IoAddress);                                                                                                                                                                               ///< CPU I/O port 8-bit read.
+typedef UINT16     (EFIAPI * SA_IO_READ_16)              (UINTN IoAddress);                                                                                                                                                                               ///< CPU I/O port 16-bit read.
+typedef UINT32     (EFIAPI * SA_IO_READ_32)              (UINTN IoAddress);                                                                                                                                                                               ///< CPU I/O port 32-bit read.
+typedef UINT8      (EFIAPI * SA_IO_WRITE_8)              (UINTN IoAddress, UINT8 Value);                                                                                                                                                                  ///< CPU I/O port 8-bit write.
+typedef UINT16     (EFIAPI * SA_IO_WRITE_16)             (UINTN IoAddress, UINT16 Value);                                                                                                                                                                 ///< CPU I/O port 16-bit write.
+typedef UINT32     (EFIAPI * SA_IO_WRITE_32)             (UINTN IoAddress, UINT32 Value);                                                                                                                                                                 ///< CPU I/O port 32-bit write.
+typedef UINT8      (EFIAPI * SA_MMIO_READ_8)             (UINTN Address);                                                                                                                                                                                 ///< Memory Mapped I/O port 8-bit read.
+typedef UINT16     (EFIAPI * SA_MMIO_READ_16)            (UINTN Address);                                                                                                                                                                                 ///< Memory Mapped I/O port 16-bit read.
+typedef UINT32     (EFIAPI * SA_MMIO_READ_32)            (UINTN Address);                                                                                                                                                                                 ///< Memory Mapped I/O port 32-bit read.
+typedef UINT64     (EFIAPI * SA_MMIO_READ_64)            (UINTN Address);                                                                                                                                                                                 ///< Memory Mapped I/O port 64-bit read.
+typedef UINT8      (EFIAPI * SA_MMIO_WRITE_8)            (UINTN Address, UINT8 Value);                                                                                                                                                                    ///< Memory Mapped I/O port 8-bit write.
+typedef UINT16     (EFIAPI * SA_MMIO_WRITE_16)           (UINTN Address, UINT16 Value);                                                                                                                                                                   ///< Memory Mapped I/O port 16-bit write.
+typedef UINT32     (EFIAPI * SA_MMIO_WRITE_32)           (UINTN Address, UINT32 Value);                                                                                                                                                                   ///< Memory Mapped I/O port 32-bit write.
+typedef UINT64     (EFIAPI * SA_MMIO_WRITE_64)           (UINTN Address, UINT64 Value);                                                                                                                                                                   ///< Memory Mapped I/O port 64-bit write.
+typedef UINT8      (EFIAPI * SA_SMBUS_READ_8)            (UINTN Address, RETURN_STATUS *Status);                                                                                                                                                          ///< Smbus 8-bit read.
+typedef UINT16     (EFIAPI * SA_SMBUS_READ_16)           (UINTN Address, RETURN_STATUS *Status);                                                                                                                                                          ///< Smbus 16-bit read.
+typedef UINT8      (EFIAPI * SA_SMBUS_WRITE_8)           (UINTN Address, UINT8 Value, RETURN_STATUS *Status);                                                                                                                                             ///< Smbus 8-bit write.
+typedef UINT16     (EFIAPI * SA_SMBUS_WRITE_16)          (UINTN Address, UINT16 Value, RETURN_STATUS *Status);                                                                                                                                            ///< Smbus 16-bit write.
+typedef UINT32     (EFIAPI * SA_GET_PCI_DEVICE_ADDRESS)  (UINT8 Bus, UINT8 Device, UINT8 Function, UINT8 Offset);                                                                                                                                         ///< Get PCI device address.
+typedef UINT32     (EFIAPI * SA_GET_PCIE_DEVICE_ADDRESS) (UINT8 Bus, UINT8 Device, UINT8 Function, UINT8 Offset);                                                                                                                                         ///< Get PCI express device address.
+typedef VOID       (EFIAPI * SA_GET_RTC_TIME)            (UINT8 *Second, UINT8 *Minute, UINT8 *Hour, UINT8 *Day, UINT8 *Month, UINT16 *Year);                                                                                                             ///< Get the current time value.
+typedef UINT64     (EFIAPI * SA_GET_CPU_TIME)            (VOID);                                                                                                                                                                                          ///< The current CPU time in milliseconds.
+typedef VOID *     (EFIAPI * SA_MEMORY_COPY)             (VOID *Destination, CONST VOID *Source, UINTN NumBytes);                                                                                                                                         ///< Perform byte copy operation.
+typedef VOID *     (EFIAPI * SA_MEMORY_SET_BYTE)         (VOID *Buffer, UINTN NumBytes, UINT8 Value);                                                                                                                                                     ///< Perform byte initialization operation.
+typedef VOID *     (EFIAPI * SA_MEMORY_SET_WORD)         (VOID *Buffer, UINTN NumWords, UINT16 Value);                                                                                                                                                    ///< Perform word initialization operation.
+typedef VOID *     (EFIAPI * SA_MEMORY_SET_DWORD)        (VOID *Buffer, UINTN NumDwords, UINT32 Value);                                                                                                                                                   ///< Perform dword initialization operation.
+typedef UINT64     (EFIAPI * SA_LEFT_SHIFT_64)           (UINT64 Data, UINTN NumBits);                                                                                                                                                                    ///< Left shift the 64-bit data value by specified number of bits.
+typedef UINT64     (EFIAPI * SA_RIGHT_SHIFT_64)          (UINT64 Data, UINTN NumBits);                                                                                                                                                                    ///< Right shift the 64-bit data value by specified number of bits.
+typedef UINT64     (EFIAPI * SA_MULT_U64_U32)            (UINT64 Multiplicand, UINT32 Multiplier);                                                                                                                                                        ///< Multiply a 64-bit data value by a 32-bit data value.
+typedef UINT64     (EFIAPI * SA_DIV_U64_U64)             (UINT64 Dividend, UINT64 Divisor, UINT64 *Remainder);                                                                                                                                            ///< Divide a 64-bit data value by a 64-bit data value.
+typedef BOOLEAN    (EFIAPI * SA_GET_SPD_DATA)            (SPD_BOOT_MODE BootMode, UINT8 SpdAddress, UINT8 *Buffer, UINT8 *Ddr3Table, UINT32 Ddr3TableSize, UINT8 *Ddr4Table, UINT32 Ddr4TableSize, UINT8 *LpddrTable, UINT32 LpddrTableSize);             ///< Read the SPD data over the SMBus, at the given SmBus SPD address and copy the data to the data structure.
+typedef UINT8      (EFIAPI * SA_GET_MC_ADDRESS_DECODE)   (UINT64 Address, SA_ADDRESS_DECODE *DramAddress);
+typedef UINT8      (EFIAPI * SA_GET_MC_ADDRESS_ENCODE)   (SA_ADDRESS_DECODE *DramAddress, UINT64 Address);
+typedef BOOLEAN    (EFIAPI * SA_GET_RANDOM_NUMBER)       (UINT32 *Rand);                                                                                                                                                                                  ///< Get the next random 32-bit number.
+typedef EFI_STATUS (EFIAPI * SA_CPU_MAILBOX_READ)        (UINT32 Type, UINT32 Command, UINT32 *Value, UINT32 *Status);                                                                                                                                    ///< Perform a CPU mailbox read.
+typedef EFI_STATUS (EFIAPI * SA_CPU_MAILBOX_WRITE)       (UINT32 Type, UINT32 Command, UINT32 Value, UINT32 *Status);                                                                                                                                     ///< Perform a CPU mailbox write.
+typedef UINT32     (EFIAPI * SA_GET_MEMORY_VDD)          (VOID *GlobalData, UINT32 DefaultVdd);                                                                                                                                                           ///< Get the current memory voltage (VDD).
+typedef UINT32     (EFIAPI * SA_SET_MEMORY_VDD)          (VOID *GlobalData, UINT32 DefaultVdd, UINT32 Value);                                                                                                                                             ///< Set the memory voltage (VDD) to the given value.
+typedef UINT32     (EFIAPI * SA_CHECKPOINT)              (VOID *GlobalData, UINT32 CheckPoint, VOID *Scratch);                                                                                                                                            ///< Check point that is called at various points in the MRC.
+typedef VOID       (EFIAPI * SA_DEBUG_HOOK)              (VOID *GlobalData, UINT16 DisplayDebugNumber);                                                                                                                                                   ///< Typically used to display to the I/O port 80h.
+typedef UINT8      (EFIAPI * SA_CHANNEL_EXIST)           (VOID *Outputs, UINT8 Channel);                                                                                                                                                                  ///< Returns whether Channel is or is not present.
+typedef INT32      (EFIAPI * SA_PRINTF)                  (VOID *Debug, UINT32 Level, char *Format, ...);                                                                                                                                                  ///< Print to output stream/device.
+typedef VOID       (EFIAPI * SA_DEBUG_PRINT)             (VOID *String);                                                                                                                                                                                  ///< Output a string to the debug stream/device.
+typedef UINT32     (EFIAPI * SA_CHANGE_MARGIN)           (VOID *GlobalData, UINT8 Param, INT32 Value0, INT32 Value1, UINT8 EnMultiCast, UINT8 Channel, UINT8 RankIn, UINT8 Byte, UINT8 BitIn, UINT8 UpdateMrcData, UINT8 SkipWait, UINT32 RegFileParam);  ///< Change the margin.
+typedef UINT8      (EFIAPI * SA_SIGN_EXTEND)             (UINT8 Value, UINT8 OldMsb, UINT8 NewMsb);                                                                                                                                                       ///< Sign extends OldMSB to NewMSB Bits (Eg: Bit 6 to Bit 7).
+typedef VOID       (EFIAPI * SA_SHIFT_PI_COMMAND_TRAIN)  (VOID *GlobalData, UINT8 Channel, UINT8 Iteration, UINT8 RankMask, UINT8 GroupMask, INT32 NewValue, UINT8 UpdateHost);                                                                           ///< Move CMD/CTL/CLK/CKE PIs during training.
+typedef VOID       (EFIAPI * SA_UPDATE_VREF)             (VOID *GlobalData, UINT8 Channel, UINT8 RankMask, UINT16 DeviceMask, UINT8 VrefType, INT32 Offset, BOOLEAN UpdateMrcData, BOOLEAN PDAmode, BOOLEAN SkipWait);                                    ///< Update the Vref value and wait until it is stable.
+typedef UINT8      (EFIAPI * SA_GET_RTC_CMOS)            (UINT8 Location);                                                                                                                                                                                ///< Get the current value of the specified RTC CMOS location.
+typedef UINT64     (EFIAPI * SA_MSR_READ_64)             (UINT32 Location);                                                                                                                                                                               ///< Get the current value of the specified MSR location.
+typedef UINT64     (EFIAPI * SA_MSR_WRITE_64)            (UINT32 Location, UINT64 Data);                                                                                                                                                                  ///< Set the current value of the specified MSR location.
+typedef VOID       (EFIAPI * SA_MRC_RETURN_FROM_SMC)     (VOID *GlobalData, UINT32 MrcStatus);                                                                                                                                                            ///< Hook function after returning from MrcStartMemoryConfiguration()
+typedef VOID       (EFIAPI * SA_MRC_DRAM_RESET)          (UINT32 PciEBaseAddress, UINT32 ResetValue);                                                                                                                                                     ///< Assert or deassert DRAM_RESET# pin; this is used in JEDEC Reset.
+typedef VOID       (EFIAPI * SA_DELAY_NS)                (VOID *GlobalData, UINT32 DelayNs);                                                                                                                                                              ///< Delay (stall) for the given amount of nanoseconds.
+typedef VOID       (EFIAPI * SA_SET_LOCK_PRMRR)          (UINT64 PrmrrBaseAddress, UINT32 PrmrrSize);
+
+
+///
+/// Function calls into the SA.
+///
+typedef struct {
+  SA_IO_READ_8               IoRead8;               ///< Offset 0:   - CPU I/O port 8-bit read.
+  SA_IO_READ_16              IoRead16;              ///< Offset 4:   - CPU I/O port 16-bit read.
+  SA_IO_READ_32              IoRead32;              ///< Offset 8:   - CPU I/O port 32-bit read.
+  SA_IO_WRITE_8              IoWrite8;              ///< Offset 12:  - CPU I/O port 8-bit write.
+  SA_IO_WRITE_16             IoWrite16;             ///< Offset 16:  - CPU I/O port 16-bit write.
+  SA_IO_WRITE_32             IoWrite32;             ///< Offset 20:  - CPU I/O port 32-bit write.
+  SA_MMIO_READ_8             MmioRead8;             ///< Offset 24:  - Memory Mapped I/O port 8-bit read.
+  SA_MMIO_READ_16            MmioRead16;            ///< Offset 28:  - Memory Mapped I/O port 16-bit read.
+  SA_MMIO_READ_32            MmioRead32;            ///< Offset 32:  - Memory Mapped I/O port 32-bit read.
+  SA_MMIO_READ_64            MmioRead64;            ///< Offset 36:  - Memory Mapped I/O port 64-bit read.
+  SA_MMIO_WRITE_8            MmioWrite8;            ///< Offset 40:  - Memory Mapped I/O port 8-bit write.
+  SA_MMIO_WRITE_16           MmioWrite16;           ///< Offset 44:  - Memory Mapped I/O port 16-bit write.
+  SA_MMIO_WRITE_32           MmioWrite32;           ///< Offset 48:  - Memory Mapped I/O port 32-bit write.
+  SA_MMIO_WRITE_64           MmioWrite64;           ///< Offset 52:  - Memory Mapped I/O port 64-bit write.
+  SA_SMBUS_READ_8            SmbusRead8;            ///< Offset 56:  - Smbus 8-bit read.
+  SA_SMBUS_READ_16           SmbusRead16;           ///< Offset 60:  - Smbus 16-bit read.
+  SA_SMBUS_WRITE_8           SmbusWrite8;           ///< Offset 64:  - Smbus 8-bit write.
+  SA_SMBUS_WRITE_16          SmbusWrite16;          ///< Offset 68:  - Smbus 16-bit write.
+  SA_GET_PCI_DEVICE_ADDRESS  GetPciDeviceAddress;   ///< Offset 72:  - Get PCI device address.
+  SA_GET_PCIE_DEVICE_ADDRESS GetPcieDeviceAddress;  ///< Offset 76:  - Get PCI express device address.
+  SA_GET_RTC_TIME            GetRtcTime;            ///< Offset 80:  - Get the current time value.
+  SA_GET_CPU_TIME            GetCpuTime;            ///< Offset 84:  - The current CPU time in milliseconds.
+  SA_MEMORY_COPY             CopyMem;               ///< Offset 88:  - Perform byte copy operation.
+  SA_MEMORY_SET_BYTE         SetMem;                ///< Offset 92:  - Perform byte initialization operation.
+  SA_MEMORY_SET_WORD         SetMemWord;            ///< Offset 96:  - Perform word initialization operation.
+  SA_MEMORY_SET_DWORD        SetMemDword;           ///< Offset 100: - Perform dword initialization operation.
+  SA_LEFT_SHIFT_64           LeftShift64;           ///< Offset 104: - Left shift the 64-bit data value by specified number of bits.
+  SA_RIGHT_SHIFT_64          RightShift64;          ///< Offset 108: - Right shift the 64-bit data value by specified number of bits.
+  SA_MULT_U64_U32            MultU64x32;            ///< Offset 112: - Multiply a 64-bit data value by a 32-bit data value.
+  SA_DIV_U64_U64             DivU64x64;             ///< Offset 116: - Divide a 64-bit data value by a 64-bit data value.
+  SA_GET_SPD_DATA            GetSpdData;            ///< Offset 120: - Read the SPD data over the SMBus, at the given SmBus SPD address and copy the data to the data structure.
+  SA_GET_RANDOM_NUMBER       GetRandomNumber;       ///< Offset 124: - Get the next random 32-bit number.
+  SA_CPU_MAILBOX_READ        CpuMailboxRead;        ///< Offset 128: - Perform a CPU mailbox read.
+  SA_CPU_MAILBOX_WRITE       CpuMailboxWrite;       ///< Offset 132: - Perform a CPU mailbox write.
+  SA_GET_MEMORY_VDD          GetMemoryVdd;          ///< Offset 136: - Get the current memory voltage (VDD).
+  SA_SET_MEMORY_VDD          SetMemoryVdd;          ///< Offset 140: - Set the memory voltage (VDD) to the given value.
+  SA_CHECKPOINT              CheckPoint;            ///< Offset 144: - Check point that is called at various points in the MRC.
+  SA_DEBUG_HOOK              DebugHook;             ///< Offset 148: - Typically used to display to the I/O port 80h.
+  SA_DEBUG_PRINT             DebugPrint;            ///< Offset 152: - Output a string to the debug stream/device.
+  SA_GET_RTC_CMOS            GetRtcCmos;            ///< Offset 156: - Get the current value of the specified RTC CMOS location.
+  SA_MSR_READ_64             ReadMsr64;             ///< Offset 160: - Get the current value of the specified MSR location.
+  SA_MSR_WRITE_64            WriteMsr64;            ///< Offset 164  - Set the current value of the specified MSR location.
+  SA_MRC_RETURN_FROM_SMC     MrcReturnFromSmc;      ///< Offset 168  - Hook function after returning from MrcStartMemoryConfiguration()
+  SA_MRC_DRAM_RESET          MrcDramReset;          ///< Offset 172  - Assert or deassert DRAM_RESET# pin; this is used in JEDEC Reset.
+  SA_DELAY_NS                MrcDelayNs;            ///< Offset 176  - Delay (stall) for the given amount of nanoseconds.
+} SA_FUNCTION_CALLS;
+
+///
+/// Function calls into the MRC.
+///
+typedef struct {
+  SA_CHANNEL_EXIST           MrcChannelExist;       ///< Offset 0:  - Returns whether Channel is or is not present.
+  SA_PRINTF                  MrcPrintf;             ///< Offset 4:  - Print to output stream/device.
+  SA_CHANGE_MARGIN           MrcChangeMargin;       ///< Offset 8:  - Change the margin.
+  SA_SIGN_EXTEND             MrcSignExtend;         ///< Offset 12: - Sign extends OldMSB to NewMSB Bits (Eg: Bit 6 to Bit 7).
+  SA_SHIFT_PI_COMMAND_TRAIN  ShiftPiCommandTrain;   ///< Offset 16: - Move CMD/CTL/CLK/CKE PIs during training.
+  SA_UPDATE_VREF             MrcUpdateVref;         ///< Offset 20: - Update the Vref value and wait until it is stable.
+} SA_MEMORY_FUNCTIONS;
+
+/**
+ Memory Configuration
+ The contents of this structure are CRC'd by the MRC for option change detection.
+ This structure is copied en mass to the MrcInput structure. If you add fields here, you must update the MrcInput structure.
+ <b>Revision 1</b>: - Initial version.
+ <b>Revision 2</b>: - Adding ChHashOverride option.
+ <b>Revision 3</b>: - Adding PDA enumeration option.
+ <b>Revision 4</b>: - Adding LPDDR4 Command Mirroring.
+ <b>Revision 5</b>: - Adding CpuBclkSpread option.
+ <b>Revision 6</b>: - Adding McParity option.
+ <b>Revision 7</b>: - Adding VddqVoltageOverride option.
+ <b>Revision 8</b>: - Adding ExtendedBankHashing option.
+ <b>Revision 9</b>: - Adding IbeccErrorInj option
+ **/
+typedef struct {
+  CONFIG_BLOCK_HEADER  Header;    ///< Offset 0-27 Config Block Header
+  UINT16  Size;                   ///< Offset 28 The size of this structure, in bytes. Must be the first entry in this structure.
+  UINT8   HobBufferSize;          ///< Offset 30 Size of HOB buffer for MRC
+
+  UINT8   SpdProfileSelected;     ///< Offset 31 SPD XMP profile selection - for XMP supported DIMM: <b>0=Default DIMM profile</b>, 1=Customized profile, 2=XMP profile 1, 3=XMP profile 2.
+
+  // The following parameters are used only when SpdProfileSelected is UserDefined (CUSTOM PROFILE)
+  UINT16  tCL;                    ///< Offset 32 User defined Memory Timing tCL value,   valid when SpdProfileSelected is CUSTOM_PROFILE: <b>0=AUTO</b>, 31=Maximum.
+  UINT16  tRCDtRP;                ///< Offset 34 User defined Memory Timing tRCD value (same as tRP), valid when SpdProfileSelected is CUSTOM_PROFILE: <b>0=AUTO</b>, 63=Maximum
+  UINT16  tRAS;                   ///< Offset 36 User defined Memory Timing tRAS value,  valid when SpdProfileSelected is CUSTOM_PROFILE: <b>0=AUTO</b>, 64=Maximum.
+  UINT16  tWR;                    ///< Offset 38 User defined Memory Timing tWR value,   valid when SpdProfileSelected is CUSTOM_PROFILE: <b>0=AUTO</b>, legal values: 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 24.
+  UINT16  tRFC;                   ///< Offset 40 User defined Memory Timing tRFC value,  valid when SpdProfileSelected is CUSTOM_PROFILE: <b>0=AUTO</b>, 1023=Maximum.
+  UINT16  tRRD;                   ///< Offset 42 User defined Memory Timing tRRD value,  valid when SpdProfileSelected is CUSTOM_PROFILE: <b>0=AUTO</b>, 15=Maximum.
+  UINT16  tWTR;                   ///< Offset 44 User defined Memory Timing tWTR value,  valid when SpdProfileSelected is CUSTOM_PROFILE: <b>0=AUTO</b>, 28=Maximum.
+  UINT16  tRTP;                   ///< Offset 46 User defined Memory Timing tRTP value,  valid when SpdProfileSelected is CUSTOM_PROFILE: <b>0=AUTO</b>, 15=Maximum. DDR4 legal values: 5, 6, 7, 8, 9, 10, 12
+  UINT16  tFAW;                   ///< Offset 48 User defined Memory Timing tFAW value,  valid when SpdProfileSelected is CUSTOM_PROFILE: <b>0=AUTO</b>, 63=Maximum.
+  UINT16  tCWL;                   ///< Offset 50 User defined Memory Timing tCWL value,  valid when SpdProfileSelected is CUSTOM_PROFILE: <b>0=AUTO</b>, 20=Maximum.
+  UINT16  tREFI;                  ///< Offset 52 User defined Memory Timing tREFI value, valid when SpdProfileSelected is CUSTOM_PROFILE: <b>0=AUTO</b>, 65535=Maximum.
+  UINT16  PciIndex;               ///< Offset 54 Pci index register address: <b>0xCF8=Default</b>
+  UINT16  PciData;                ///< Offset 56 Pci data register address: <b>0xCFC=Default</b>
+  UINT16  VddVoltage;             ///< Offset 58 DRAM voltage (Vdd) in millivolts: <b>0=Platform Default (no override)</b>, 1200=1.2V, 1350=1.35V etc.
+  UINT16  Idd3n;                  ///< Offset 60 EPG Active standby current (Idd3N) in milliamps from DIMM datasheet.
+  UINT16  Idd3p;                  ///< Offset 62 EPG Active power-down current (Idd3P) in milliamps from DIMM datasheet.
+
+  UINT32  EccSupport:1;              ///< Offset 64 Bit 0  - DIMM Ecc Support option - for Desktop only: 0=Disable, <b>1=Enable</b>
+  UINT32  MrcSafeConfig:1;           ///<           Bit 1  - MRC Safe Mode: <b>0=Disable</b>, 1=Enable
+  UINT32  RemapEnable:1;             ///<           Bit 2  - This option is used to control whether to enable/disable memory remap above 4GB: 0=Disable, <b>1=Enable</b>.
+  UINT32  ScramblerSupport:1;        ///<           Bit 3  - Memory scrambler support: 0=Disable, <b>1=Enable</b>
+  UINT32  Vc1ReadMeter:1;            ///<           Bit 4  - VC1 Read Metering Enable: 0=Disable, <b>1=Enable</b>
+  UINT32  ForceSingleSubchannel:1;   ///<           Bit 5  - TRUE means use SubChannel0 only (for LPDDR4): <b>0=Disable</b>, 1=Enable
+  UINT32  SimicsFlag:1;              ///<           Bit 6  - Option to Enable SIMICS: 0=Disable, <b>1=Enable</b>
+  UINT32  Ddr4DdpSharedClock:1;      ///<           Bit 7  - Select if CLK0 is shared between Rank0 and Rank1 in DDR4 DDP package. <b>0=Not shared</b>, 1=Shared
+  UINT32  SharedZqPin:1;             ///<           Bit 8  - Select if the ZQ resistor is shared between Ranks in DDR4/LPDDR4 DRAM Packages <b>0=Not Shared</b>, 1=Shared
+  UINT32  LpDqsOscEn:1;              ///<           Bit 9  - LPDDR Write DQ/DQS Retraining: 0=Disable, <b>1=Enable</b>
+  UINT32  RmtPerTask:1;              ///<           Bit 10 - Rank Margin Tool Per Task. <b>0 = Disabled</b>, 1 = Enabled
+  UINT32  TrainTrace:1;              ///<           Bit 11 - Trained state tracing debug. <b>0 = Disabled</b>, 1 = Enabled
+  UINT32  SafeMode:1;                ///<           Bit 12 - Define if safe mode is enabled for MC/IO
+  UINT32  MsHashEnable:1;            ///<           Bit 13 - Controller Hash Enable: 0=Disable, <b>1=Enable</b>
+  UINT32  DisPgCloseIdleTimeout:1;   ///<           Bit 14 - Disable Page Close Idle Timeout: 0=Enable, <b>1=Disable</b>
+  UINT32  Ibecc:1;                   ///<           Bit 15 - Inband ECC - for LPDDR4, LPDDR5 and DDR4 only: <b>0=Disable</b>, 1=Enable
+  UINT32  IbeccParity:1;             ///<           Bit 16 - Inband ECC Parity Control - for LPDDR4, LPDDR5 and DDR4 only: <b>0=Disable</b>, 1=Enable
+  UINT32  IbeccOperationMode:2;      ///<           Bits 17:18 - Inband ECC Operation Mode: 0=Functional Mode protects requests based on the address range, <b>1=Makes all requests non protected and ignore range checks</b>, 2=Makes all requests protected and ignore range checks
+  UINT32  ChHashOverride:1;          ///<           Bit 19 - Select if Channel Hash setting values will be taken from input parameters or automatically taken from POR values depending on DRAM type detected.
+  UINT32  McParity:1;                ///<           Bit 20 - MC Parity Control - Enable Parity for CMI/MC: <b>0=Disable</b>, 1=Enable
+  UINT32  IbeccErrorInj:1;           ///<           Bit 21 - In-Band ECC Error Injection: 1=Enable, <b>0=Disable</b>
+  UINT32  RsvdO64B22t31:10;          ///<           Bits 22:31 reserved
+  /**
+   Disables a DIMM slot in the channel even if a DIMM is present\n
+   Array index represents the channel number (0 = channel 0, 1 = channel 1)\n
+     <b>0x0 = DIMM 0 and DIMM 1 enabled</b>\n
+     0x1 = DIMM 0 disabled, DIMM 1 enabled\n
+     0x2 = DIMM 0 enabled, DIMM 1 disabled\n
+     0x3 = DIMM 0 and DIMM 1 disabled (will disable the whole channel)\n
+  **/
+  UINT8   DisableDimmChannel[MEM_CFG_MAX_CONTROLLERS][MEM_CFG_MAX_CHANNELS]; ///< Offset 68-75
+  UINT8   Ratio;                  ///< Offset 76 DDR Frequency ratio, to multiply by 133 or 100 MHz depending on RefClk. <b>0 = Auto</b>
+  UINT8   ProbelessTrace;         ///< Offset 77 Probeless Trace: <b>0=Disabled</b>, <b>1=Enabled</b>
+  /**
+     - Channel Hash Enable.\n
+    NOTE: BIT7 will interleave the channels at a 2 cache-line granularity, BIT8 at 4 and BIT9 at 8\n
+    0=BIT6, <B>1=BIT7</B>, 2=BIT8, 3=BIT9
+  **/
+  UINT8   ChHashInterleaveBit;    ///< Offset 78 Option to select interleave Address bit. Valid values are 0 - 3 for BITS 6 - 9 (Valid values for BDW are 0-7 for BITS 6 - 13)
+  UINT8   SmramMask;              ///< Offset 79 Reserved memory ranges for SMRAM
+  UINT32  BClkFrequency;          ///< Offset 80 Base reference clock value, in Hertz: <b>100000000 = 100Hz</b>, 125000000=125Hz, 167000000=167Hz, 250000000=250Hz
+
+  /// Training Algorithms 1 Offset 84
+  UINT32 ECT:1;                   ///< Bit 0 - Enable/Disable Early Command Training. Note it is not recommended to change this setting from the default value: <b>0=Disable</b>, 1=Enable.
+  UINT32 SOT:1;                   ///< Bit 1 - Enable/Disable Sense Amp Offset Training. Note it is not recommended to change this setting from the default value: 0=Disable, <b>1=Enable</b>.
+  UINT32 ERDMPRTC2D:1;            ///< Bit 2 - Enable/Disable Early ReadMPR Timing Centering 2D. Note it is not recommended to change this setting from the default value: 0=Disable, <b>1=Enable</b>.
+  UINT32 RDMPRT:1;                ///< Bit 3 - Enable/Disable Read MPR Training. Note it is not recommended to change this setting from the default value: 0=Disable, <b>1=Enable</b>.
+  UINT32 RCVET:1;                 ///< Bit 4 - Enable/Disable Receive Enable Training. Note it is not recommended to change this setting from the default value: 0=Disable, <b>1=Enable</b>.
+  UINT32 JWRL:1;                  ///< Bit 5 - Enable/Disable JEDEC Write Leveling Training. Note it is not recommended to change this setting from the default value: 0=Disable, <b>1=Enable</b>.
+  UINT32 EWRTC2D:1;               ///< Bit 6 - Enable/Disable Early Write Time Centering 2D Training. Note it is not recommended to change this setting from the default value: 0=Disable, <b>1=Enable</b>.
+  UINT32 ERDTC2D:1;               ///< Bit 7 - Enable/Disable Early Read Time Centering 2D Training. Note it is not recommended to change this setting from the default value: 0=Disable, <b>1=Enable</b>.
+  UINT32 WRTC1D:1;                ///< Bit 8 - Enable/Disable 1D Write Timing Centering Training. Note it is not recommended to change this setting from the default value: 0=Disable, <b>1=Enable</b>.
+  UINT32 WRVC1D:1;                ///< Bit 9 - Enable/Disable 1D Write Voltage Centering Training. Note it is not recommended to change this setting from the default value: 0=Disable, <b>1=Enable</b>.
+  UINT32 RDTC1D:1;                ///< Bit 10 - Enable/Disable 1D Read Timing Centering Training. Note it is not recommended to change this setting from the default value: 0=Disable, <b>1=Enable</b>.
+  UINT32 DIMMODTT:1;              ///< Bit 11 - Enable/Disable DIMM ODT Training. Note it is not recommended to change this setting from the default value: <b>0=Disable</b>, 1=Enable.
+  UINT32 DIMMRONT:1;              ///< Bit 12 - Enable/Disable DIMM RON training. Note it is not recommended to change this setting from the default value: 0=Disable, <b>1=Enable</b>.
+  UINT32 WRDSEQT:1;               ///< Bit 13 - Enable/Disable Write Drive Strength / Equalization Training 2D. Note it is not recommended to change this setting from the default value: <b>0=Disable</b>, 1=Enable.
+  UINT32 WRSRT:1;                 ///< Bit 14 - Enable/Disable Write Slew Rate traning. Note it is not recommended to change this setting from the default value: 0=Disable, <b>1=Enable.</b>
+  UINT32 RDODTT:1;                ///< Bit 15 - Enable/Disable Read ODT Training. Note it is not recommended to change this setting from the default value: <b>0=Disable</b>, 1=Enable.
+  UINT32 RDEQT:1;                 ///< Bit 16 - Enable/Disable Read Equalization Training. Note it is not recommended to change this setting from the default value: <b>0=Disable</b>, 1=Enable.
+  UINT32 RDAPT:1;                 ///< Bit 17 - Enable/Disable Read Amplifier Power Training. Note it is not recommended to change this setting from the default value: <b>0=Disable</b>, 1=Enable.
+  UINT32 WRTC2D:1;                ///< Bit 18 - Enable/Disable 2D Write Timing Centering Training. Note it is not recommended to change this setting from the default value: 0=Disable, <b>1=Enable</b>.
+  UINT32 RDTC2D:1;                ///< Bit 19 - Enable/Disable 2D Read Timing Centering Training. Note it is not recommended to change this setting from the default value: 0=Disable, <b>1=Enable</b>.
+  UINT32 WRVC2D:1;                ///< Bit 20 - Enable/Disable 2D Write Voltage Centering Training. Note it is not recommended to change this setting from the default value: 0=Disable, <b>1=Enable</b>.
+  UINT32 RDVC2D:1;                ///< Bit 21 - Enable/Disable 2D Read Voltage Centering Training. Note it is not recommended to change this setting from the default value: 0=Disable, <b>1=Enable</b>.
+  UINT32 CMDVC:1;                 ///< Bit 22 - Enable/Disable Command Vref Centering Training. Note it is not recommended to change this setting from the default value 0=Disable, <b>1=Enable</b>.
+  UINT32 LCT:1;                   ///< Bit 23 - Enable/Disable Late Command Training. Note it is not recommended to change this setting from the default value: 0=Disable, <b>1=Enable</b>.
+  UINT32 RTL:1;                   ///< Bit 24 - Enable/Disable Round Trip Latency function. Note it is not recommended to change this setting from the default value: 0=Disable, <b>1=Enable</b>.
+  UINT32 TAT:1;                   ///< Bit 25 - Enable/Disable Turn Around Time function. Note it is not recommended to change this setting from the default value: <b>0=Disable</b>, 1=Enable.
+  UINT32 RMT:1;                   ///< Bit 26 - Enable/Disable Rank Margin Tool function: <b>0=Disable</b>, 1=Enable.
+  UINT32 MEMTST:1;                ///< Bit 27 - Enable/Disable Memory Test function: <b>0=Disable</b>, 1=Enable.
+  UINT32 ALIASCHK:1;              ///< Bit 28 - Enable/Disable DIMM SPD Alias Check: 0=Disable, <b>1=Enable</b>
+  UINT32 RCVENC1D:1;              ///< Bit 29 - Enable/Disable Receive Enable Centering Training (LPDDR Only). Note it is not recommended to change this setting from the default value: <b>0=Disable</b>, 1=Enable
+  UINT32 RMC:1;                   ///< Bit 30 - Enable/Disable Retrain Margin Check.  Note it is not recommended to change this setting from the default value: <b>0=Disable</b>, 1=Enable
+  UINT32 WRDSUDT:1;               ///< Bit 31 - Enable/Disable Write Drive Strength Up/Dn independently. Note it is not recommended to change this setting from the default value: <b>0=Disable</b>, 1=Enable
+  /// Training Algorithms 2 Offset 88
+  UINT32 DCC       : 1;           ///< Bit 0  - Enable/Disable Duty Cycle Correction: 0=Disable, 1=Enable.
+  UINT32 RDVC1D    : 1;           ///< Bit 1  - Enable/Disable Read Voltage Centering 1D: 0=Disable, 1=Enable.
+  UINT32 TXTCO     : 1;           ///< Bit 2  - Enable/Disable Write TCO Comp Training: 0=Disable, 1=Enable.
+  UINT32 CLKTCO    : 1;           ///< Bit 3  - Enable/Disable Clock TCO Comp Training: 0=Disable, 1=Enable.
+  UINT32 CMDSR     : 1;           ///< Bit 4  - Enable/Disable CMD Slew Rate Training: 0=Disable, 1=Enable.
+  UINT32 CMDDSEQ   : 1;           ///< Bit 5  - Enable/Disable CMD Drive Strength and Tx Equalization: 0=Disable, 1=Enable.
+  UINT32 DIMMODTCA : 1;           ///< Bit 6  - Enable/Disable Dimm ODT CA Training: 0=Disable, 1=Enable.
+  UINT32 TXTCODQS  : 1;           ///< Bit 7  - Enable/Disable Write TCO Dqs Training: 0=Disable, 1=Enable.
+  UINT32 CMDDRUD   : 1;           ///< Bit 8  - Enable/Disable CMD/CTL Drive Strength Up/Dn 2D: 0=Disable, 1=Enable.
+  UINT32 VCCDLLBP  : 1;           ///< Bit 9  - Enable/Disable VccDLL bypass to VccIOG training: 0=Disable, 1=Enable.
+  UINT32 PVTTDNLP  : 1;           ///< Bit 10 - Enable/Disable PanicVttDnLp Training: 0=Disable, 1=Enable.
+  UINT32 RDVREFDC  : 1;           ///< Bit 11 - Enable/Disable Read Vref Decap Training: 0=Disable, 1=Enable.
+  UINT32 VDDQT     : 1;           ///< Bit 12 - Enable/Disable Vddq Training: 0=Disable, 1=Enable.
+  UINT32 RMTBIT    : 1;           ///< Bit 13 - Enable/Disable Rank Margin Tool Per Bit: 0=Disable, 1=Enable.
+  UINT32 PDA       : 1;           ///< BIT 14 - Enable/Disable PDA Enumeration Training. Note it is not recommended to change this setting from the default value: 0=Disable, <b>1=Enable</b>.
+  UINT32 WRITE0    : 1;           ///< BIT 15 - Write0 feature enablement
+  UINT32 ReservedBits2 :16;       ///< Bits 16:31 - Reserved
+
+  UINT32  MrcTimeMeasure:1;         ///< Offset 92 Bit 0  - Enables serial debug level to display the MRC execution times only: <b>0=Disable</b>, 1=Enable
+  UINT32  MrcFastBoot:1;            ///<           Bit 1  - Enables the MRC fast boot path for faster cold boot execution: 0=Disable, <b>1=Enable</b>
+  UINT32  DqPinsInterleaved:1;      ///<           Bit 2  - Interleaving mode of DQ/DQS pins which depends on board routing: <b>0=Disable</b>, 1=Enable
+  UINT32  RankInterleave:1;         ///<           Bit 3  - Rank Interleave Mode: 0=Disable, <b>1=Enable</b>
+  UINT32  EnhancedInterleave:1;     ///<           Bit 4  - Enhanced Interleave Mode: 0=Disable, <b>1=Enable</b>
+  UINT32  WeaklockEn:1;             ///<           Bit 5  - Weak Lock Enable: 0=Disable, <b>1=Enable</b>
+  UINT32  ChHashEnable:1;           ///<           Bit 6  - Channel Hash Enable: 0=Disable, <b>1=Enable</b>
+  UINT32  EnablePwrDn:1;            ///<           Bit 7  - Enable Power Down control for DDR: 0=PCODE control, <b>1=BIOS control</b>
+  UINT32  EnablePwrDnLpddr:1;       ///<           Bit 8  - Enable Power Down for LPDDR: 0=PCODE control, <b>1=BIOS control</b>
+  UINT32  SrefCfgEna:1;             ///<           Bit 9  - Enable Self Refresh: 0=Disable, <b>1=Enable</b>
+  UINT32  ThrtCkeMinDefeatLpddr:1;  ///<           Bit 10 - Throttler CKE min defeature for LPDDR: 0=Disable, <b>1=Enable</b>
+  UINT32  ThrtCkeMinDefeat:1;       ///<           Bit 11 - Throttler CKE min defeature: <b>0=Disable</b>, 1=Enable
+  UINT32  AutoSelfRefreshSupport:1; ///<           Bit 12 - FALSE = No auto self refresh support, <b>TRUE = auto self refresh support</b>
+  UINT32  ExtTemperatureSupport:1;  ///<           Bit 13 - FALSE = No extended temperature support, <b>TRUE = extended temperature support</b>
+  UINT32  MobilePlatform:1;         ///<           Bit 14 - Memory controller device id indicates: <b>TRUE if mobile</b>, FALSE if not. Note: This will be auto-detected and updated.
+  UINT32  Force1Dpc:1;              ///<           Bit 15 - TRUE means force one DIMM per channel, <b>FALSE means no limit</b>
+  UINT32  ForceSingleRank:1;        ///<           Bit 16 - TRUE means use Rank0 only (in each DIMM): <b>0=Disable</b>, 1=Enable
+  UINT32  VttTermination:1;         ///<           Bit 17 - Vtt Termination for Data ODT: <b>0=Disable</b>, 1=Enable
+  UINT32  VttCompForVsshi:1;        ///<           Bit 18 - Enable/Disable Vtt Comparator For Vsshi: <b>0=Disable</b>, 1=Enable
+  UINT32  ExitOnFailure:1;          ///<           Bit 19 - MRC option for exit on failure or continue on failure: 0=Disable, <b>1=Enable</b>
+  UINT32  NewFeatureEnable1:1;      ///<           Bit 20 - Generic enable knob for new feature set 1 <b>0: Disable </b>; 1: Enable
+  UINT32  NewFeatureEnable2:1;      ///<           Bit 21 - Generic enable knob for new feature set 2 <b>0: Disable </b>; 1: Enable
+  UINT32  RhPrevention:1;           ///<           Bit 22 - RH Prevention Enable/Disable: 0=Disable, <b>1=Enable</b>
+  UINT32  RhSolution:1;             ///<           Bit 23 - Type of solution to be used for RHP - 0/1 = HardwareRhp/Refresh2x
+  UINT32  RefreshPanicWm:4;         ///<           Bit 24-27 - Refresh Panic Watermark, Range 1-8, default 8.
+  UINT32  RefreshHpWm:4;            ///<           Bit 28-31 - Refresh High Profile Watermark, Range 1-7, default 7.
+  UINT32  VddSettleWaitTime;      ///< Offset 96 Amount of time in microseconds to wait for Vdd to settle on top of 200us required by JEDEC spec: <b>Default=0</b>
+  UINT16  SrefCfgIdleTmr;         ///< Offset 100 Self Refresh idle timer: <b>512=Minimal</b>, 65535=Maximum
+  UINT16  ChHashMask;             ///< Offset 102 Channel Hash Mask: 0x0001=BIT6 set(Minimal), 0x3FFF=BIT[19:6] set(Maximum), <b>0x30CE= BIT[19:18, 13:12 ,9:7] set</b>
+  UINT16  DdrFreqLimit;           ///< Offset 104 Memory Frequency setting: 3=1067, 5=1333, 7=1600, 9=1867, 11=2133, 13=2400, <b>15=2667</b>
+  UINT8   MaxRttWr;               ///< Offset 106 Maximum DIMM RTT_WR to use in power training: <b>0=ODT Off</b>, 1 = 120 ohms
+  UINT8   ThrtCkeMinTmr;          ///< Offset 107 Throttler CKE min timer: 0=Minimal, 0xFF=Maximum, <b>0x00=Default</b>
+  UINT8   ThrtCkeMinTmrLpddr;     ///< Offset 108 Throttler CKE min timer for LPDDR: 0=Minimal, 0xFF=Maximum, <b>0x00=Default</b>
+  BOOLEAN PerBankRefresh;         ///< Offset 109 Enables and Disables the per bank refresh.  This only impacts memory technologies that support PBR: LPDDR3, LPDDR4.  FALSE=Disabled, <b>TRUE=Enabled</b>
+  UINT8   SaGv;                   ///< Offset 110 SA GV: <b>0=Disabled</b>, 1=Point1, 2=Point2, 3=Point3, 4=Point4, 5=Enabled
+  UINT8   NModeSupport;           ///< Offset 111 Memory N Mode Support - Enable user to select Auto, 1N or 2N: <b>0=AUTO</b>, 1=1N, 2=2N.
+  UINT8   RefClk;                 ///< Offset 112 Selects the DDR base reference clock. 0x01 = 100MHz, <b>0x00 = 133MHz</b>
+  UINT8   EnCmdRate;              ///< Offset 113 CMD Rate Enable: 0=Disable, 5=2 CMDs, <b>7=3 CMDs</b>, 9=4 CMDs, 11=5 CMDs, 13=6 CMDs, 15=7 CMDs
+  UINT8   Refresh2X;              ///< Offset 114 Refresh 2x: <b>0=Disable</b>, 1=Enable for WARM or HOT, 2=Enable for HOT only
+  UINT8   EpgEnable;              ///< Offset 115 Enable Energy Performance Gain.
+  UINT8   UserThresholdEnable;    ///< Offset 116 Flag to manually select the DIMM CLTM Thermal Threshold, 0=Disable,  1=Enable, <b>0=Default</b>
+  UINT8   UserBudgetEnable;       ///< Offset 117 Flag to manually select the Budget Registers for CLTM Memory Dimms , 0=Disable,  1=Enable, <b>0=Default</b>
+  UINT8   RetrainOnFastFail;      ///< Offset 118 Restart MRC in Cold mode if SW MemTest fails during Fast flow. 0 = Disabled, <b>1 = Enabled</b>
+  UINT8   PowerDownMode;          ///< Offset 119 CKE Power Down Mode: <b>0xFF=AUTO</b>, 0=No Power Down, 1= APD mode, 6=PPD-DLL Off mode
+  UINT8   PwdwnIdleCounter;       ///< Offset 120 CKE Power Down Mode Idle Counter: 0=Minimal, 255=Maximum, <b>0x80=0x80 DCLK</b>
+  UINT8   CmdRanksTerminated;     ///< Offset 121 LPDDR: Bitmask of ranks that have CA bus terminated. <b>0x01=Default, Rank0 is terminating and Rank1 is non-terminating</b>
+  UINT16  MsHashMask;             ///< Offset 122 Controller Hash Mask: 0x0001=BIT6 set(Minimal), 0x3FFF=BIT[19:6] set(Maximum), <b>0x30CE= BIT[19:18, 13:12 ,9:7] set</b>
+  UINT32  Lp5CccConfig;           ///< Offset 124 BitMask where bits [3:0] are controller 0 Channel [3:0] and [7:4] are Controller 1 Channel [3:0].  0 selects Ascending mapping and 1 selects Descending mapping.
+  UINT8   RMTLoopCount;           ///< Offset 128 Indicates the Loop Count to be used for Rank Margin Tool Testing: 1=Minimal, 32=Maximum, 0=AUTO, <b>0=Default</b>
+  UINT8   MsHashInterleaveBit;    ///< Offset 129 Option to select interleave Address bit. Valid values are 0 - 3 for BITS 6 - 9
+  UINT8   GearRatio;              ///< Offset 130 This input control's the current gear expressed as an integer when SAGV is disabled: <b>0=Default</b>, 1, 2.
+  UINT8   Ddr4OneDpc;             ///< Offset 131 DDR4 1DPC performance feature: 0 - Disabled; 1 - Enabled on DIMM0 only, 2 - Enabled on DIMM1 only; 3 - Enabled on both DIMMs. (bit [0] - DIMM0, bit [1] - DIMM1)
+  UINT32  BclkRfiFreq[MEM_MAX_SAGV_POINTS]; ///< Offset 132 Bclk RFI Frequency for each SAGV point in Hz units. 98000000Hz = 98MHz <b>0 - No RFI Tuning</b>. Range is 98Mhz-100Mhz.
+  UINT16  SaGvFreq[MEM_MAX_SAGV_POINTS];    ///< Offset 148 Frequency per SAGV point.  0 is Auto, otherwise holds the frequency value expressed as an integer: <b>0=Default</b>, 1067, 1333, 1600, 1800, 1867, etc.
+  /**
+    Offset 156 Gear ratio per SAGV point.  0 is Auto, otherwise holds the Gear ratio expressed as an integer: <b>0=Default</b>, 1, 2.
+      Only valid combinations of Gear Ratio per point is:
+      | point | set1 | set2 | set3
+      | 0     | 1    | 2    | 2
+      | 1     | 1    | 2    | 2
+      | 2     | 1    | 2    | 2
+      | 3     | 1    | 2    | 1
+  **/
+  UINT8   SaGvGear[MEM_MAX_SAGV_POINTS];                      ///< Offset 156
+  UINT8   IbeccProtectedRegionEnable[MEM_MAX_IBECC_REGIONS];  ///< Offset 160 Enable use of address range for ECC Protection:  <b>0=Default</b>, 1
+  UINT16  IbeccProtectedRegionBase[MEM_MAX_IBECC_REGIONS];    ///< Offset 168 Base address for address range of ECC Protection:  <b>0=Default</b>, 1
+  UINT16  IbeccProtectedRegionMask[MEM_MAX_IBECC_REGIONS];    ///< Offset 184 Mask address for address range of ECC Protection:  <b>0=Default</b>, 1
+  UINT32  CmdMirror;              ///< Offset 200 BitMask where bits [3:0] are controller 0 Channel [3:0] and [7:4] are Controller 1 Channel [3:0].  0 = No Command Mirror and 1 = Command Mirror.
+  UINT8   CpuBclkSpread;          ///< Offset 204 CPU BCLK Spread Specturm: 0 = Disabled; <b>1 = Enabled</b>
+  UINT8   ExtendedBankHashing;    ///< Offset 205 Enable EBH Extended Bank Hashing: 0=Disabled; <b>1 = Enabled</b>.
+  UINT16  VddqVoltageOverride;    ///< Offset 206 VccddqVoltage override in # of 1mV
+  UINT8   MarginLimitCheck;                                   ///< Offset 208 Margin limit check enable: <b>0=Disable</b>, 1=L1 only, 2=L2 only, 3=Both L1 and L2
+  UINT8   RsvdO209;                                           ///< Offset 209
+  UINT16  MarginLimitL2;                                      ///< Offset 210 Margin limit check L2 threshold: <b>100=Default</b>
+} MEMORY_CONFIGURATION;
+
+/// Memory Configuration
+/// The contents of this structure are not CRC'd by the MRC for option change detection.
+/// <b>Revision 1</b>:  - Initial version.
+/// <b>Revision 2</b>:  - Added MemTestOnWarmBoot
+typedef struct {
+  CONFIG_BLOCK_HEADER      Header;              ///< Offset 0-23 Config Block Header
+  SA_FUNCTION_CALLS        SaCall;              ///< Offset 24   Function calls into the SA.
+  SA_MEMORY_FUNCTIONS      MrcCall;             ///< Offset 204  Function calls into the MRC.
+  SPD_DATA_BUFFER          *SpdData;            ///< Offset 240  Memory SPD data, will be used by the MRC when SPD SmBus address is zero.
+  UINT32                   Reserved0;
+  SA_MEMORY_DQDQS_MAPPING  *DqDqsMap;           ///< Offset 244  LPDDR DQ bit and DQS byte swizzling between CPU and DRAM.
+  SA_MEMORY_RCOMP          *RcompData;          ///< Offset 248  DDR RCOMP resistors and target values.
+  UINT64                   PlatformMemorySize;  ///< Offset 252  The minimum platform memory size required to pass control into DXE
+  UINT32                   CleanMemory:1;       ///< Offset 256  Ask MRC to clear memory content: <b>FALSE=Do not Clear Memory</b>; TRUE=Clear Memory
+  UINT32                   ReservedBits5:31;
+  /**
+   Sets the serial debug message level\n
+     0x00 = Disabled\n
+     0x01 = Errors only\n
+     0x02 = Errors and Warnings\n
+     <b>0x03 = Errors, Warnings, and Info</b>\n
+     0x04 = Errors, Warnings, Info, and Events\n
+     0x05 = Displays Memory Init Execution Time Summary only\n
+  **/
+  UINT8   SerialDebugLevel;                     ///< Offset 260
+  UINT8   MemTestOnWarmBoot;                    ///< Offset 261  Run Base Memory Test On WarmBoot:  0=Disabled, <b>1=Enabled</b>
+  UINT8   Reserved11[2];                        ///< Offset 262 - 263  Reserved
+} MEMORY_CONFIG_NO_CRC;
+#pragma pack(pop)
+
+#endif // _MEMORY_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Overclocking/OverclockingConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Overclocking/OverclockingConfig.h
new file mode 100644
index 0000000000..462c02cef1
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Overclocking/OverclockingConfig.h
@@ -0,0 +1,236 @@
+/** @file
+  Overclocking Config Block.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _OVERCLOCKING_PREMEM_CONFIG_H_
+#define _OVERCLOCKING_PREMEM_CONFIG_H_
+
+#define OVERCLOCKING_CONFIG_REVISION 9
+
+extern EFI_GUID gOverclockingPreMemConfigGuid;
+
+#pragma pack (push,1)
+
+//
+// Max number of VF point offset
+//
+#ifndef CPU_OC_MAX_VF_POINTS
+#define CPU_OC_MAX_VF_POINTS   0xF
+#endif
+
+#ifndef CPU_OC_MAX_CORES
+#define CPU_OC_MAX_CORES   8
+#endif
+/**
+  Overclocking Configuration Structure.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>
+  - Add PerCoreHtDisable
+  <b>Revision 3</b>
+  - Add Avx2VoltageScaleFactor and Avx512VoltageScaleFactor
+  <b>Revision 4</b>
+  - Add CoreVfPointOffsetMode & CoreVfPointOffset & CoreVfPointRatio & CoreVfPointCount
+  <b>Revision 5</b>
+  - Change OcLock default to 'Enabled'
+  <b>Revision 6</b>:
+  - Add DisableCoreMask.
+  <b>Revision 7</b>
+    Add UnlimitedIccMax
+  <b>Revision 8</b>
+  - Add PerCoreRatioOverride and PerCoreRatio for Per Core PState overclocking.
+  <b>Revision 9</b>
+  - Add VccInVoltageOverride.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  /**
+  Overclocking support. This controls whether OC mailbox transactions are sent.
+  If disabled, all policies in this config block besides OcSupport and OcLock will be ignored.
+  <b>0: Disable</b>;
+  1: Enable.
+  @note If PcdOverclockEnable is disabled, this should also be disabled.
+  **/
+  UINT32 OcSupport            :  1;
+  UINT32 OcLock               :  1;               ///< If enabled, sets OC lock bit in MSR 0x194[20], locking the OC mailbox and other OC configuration settings.; 0: Disable; <b>1: Enable (Lock)</b>.
+  /**
+  Core voltage mode, specifies which voltage mode the processor will be operating.
+  <b>0: Adaptive Mode</b> allows the processor to interpolate a voltage curve when beyond fused P0 range;
+  1: Override, sets one voltage for for the entire frequency range, Pn-P0.
+  **/
+  UINT32 CoreVoltageMode      :  1;
+  UINT32 CorePllVoltageOffset :  6;               ///< Core PLL voltage offset. <b>0: No offset</b>. Range 0-63 in 17.5mv units.
+  UINT32 Avx2RatioOffset      :  5;               ///< AVX2 Ratio Offset. <b>0: No offset</b>. Range is 0-31. Used to lower the AVX ratio to maximize possible ratio for SSE workload.
+  UINT32 Avx3RatioOffset      :  5;               ///< AVX3 Ratio Offset. <b>0: No offset</b>. Range is 0-31. Used to lower the AVX3 ratio to maximize possible ratio for SSE workload.
+  UINT32 BclkAdaptiveVoltage  :  1;               ///< Bclk Adaptive Voltage enable/disable. <b>0: Disabled</b>, 1: Enabled. When enabled, the CPU V/F curves are aware of BCLK frequency when calculated.
+  /**
+  Ring Downbin enable/disable.
+  When enabled, the CPU will force the ring ratio to be lower than the core ratio.
+  Disabling will allow the ring and core ratios to run at the same frequency.
+  Uses OC Mailbox command 0x19.
+  0: Disables Ring Downbin feature. <b>1: Enables Ring downbin feature.</b>
+  **/
+  UINT32 RingDownBin          :  1;
+  /**
+  Ring voltage mode, specifies which voltage mode the processor will be operating.
+  <b>0: Adaptive Mode</b> allows the processor to interpolate a voltage curve when beyond fused P0 range;
+  1: Override, sets one voltage for for the entire frequency range, Pn-P0.
+  **/
+  UINT32 RingVoltageMode      :  1;
+  UINT32 GtVoltageMode        :  1;    ///< Specifies whether GT voltage is operating in Adaptive or Override mode: <b>0=Adaptive</b>, 1=Override
+  UINT32 RealtimeMemoryTiming :  1;    ///< Enable/Disable the message sent to the CPU to allow realtime memory timing changes after MRC_DONE. <b>0=Disable</b>, 1=Enable
+  UINT32 FivrFaults           :  1;    ///< Fivr Faults. Enable or Disable FIVR Faults. 0: Disabled, <b>1: Enabled.</b>
+  UINT32 FivrEfficiency       :  1;    ///< Fivr Efficiency Management. 0: Disabled, <b>1: Enabled.</b>
+  /**
+  Selects Core Voltage & Frequency Point Offset between Legacy and Selection modes.
+  Need Reset System after enabling OverClocking Feature to Initialize the default value.
+  <b>0: In Legacy Mode, setting a global offset for the entire VF curve.</b>
+  1: In Selection modes, setting a selected VF point.
+  **/
+  UINT32 CoreVfPointOffsetMode : 1;
+  UINT32 UnlimitedIccMax      :  1;    ///< Support Unlimited ICCMAX more than maximum value 255.75A.  <b>0: Disabled</b>, 1: Enabled.
+  UINT32 PerCoreRatioOverride :  1;              ///< Enable or disable Per Core PState OC supported by writing OCMB 0x1D to program new favored core ratio to each Core. <b>0: Disable</b>, 1: enable
+  UINT32 DynamicMemoryChange  :  1;   ///< Dynamic Memory Timings Changes; <b>0: Disabled</b>; 1: Enabled.
+  UINT32 RsvdBits             :  2;    ///< Reserved for future use
+
+  /**
+  Maximum core turbo ratio override allows to increase CPU core frequency beyond the fused max turbo ratio limit (P0).
+  <b>0. no override/HW defaults.</b>. Range 0-85.
+  **/
+  UINT8  CoreMaxOcRatio;
+  UINT8  GtMaxOcRatio;                 ///< Maximum GT turbo ratio override: 0=Minimal, 60=Maximum, <b>0=AUTO</b>
+  /**
+  Maximum ring ratio override allows to increase CPU ring frequency beyond the fused max ring ratio limit.
+  <b>0. no override/HW defaults.</b>. Range 0-85.
+  **/
+  UINT8  RingMaxOcRatio;
+  UINT8  RsvdByte1;
+  /**
+  The core voltage override which is applied to the entire range of cpu core frequencies.
+  Used when CoreVoltageMode = Override.
+  <b>0. no override</b>. Range 0-2000 mV.
+  **/
+  UINT16 CoreVoltageOverride;
+  /**
+  Adaptive Turbo voltage target used to define the interpolation voltage point when the cpu is operating in turbo mode range.
+  Used when CoreVoltageMode = Adaptive.
+  <b>0. no override</b>. Range 0-2000mV.
+  **/
+  UINT16 CoreVoltageAdaptive;
+  /**
+  The core voltage offset applied on top of all other voltage modes. This offset is applied over the entire frequency range.
+  This is a 2's complement number in mV units. <b>Default: 0</b> Range: -1000 to 1000.
+  **/
+  INT16  CoreVoltageOffset;
+  /**
+  The ring voltage override which is applied to the entire range of cpu ring frequencies.
+  Used when RingVoltageMode = Override.
+  <b>0. no override</b>. Range 0-2000 mV.
+  **/
+  UINT16 RingVoltageOverride;
+  /**
+  Adaptive Turbo voltage target used to define the interpolation voltage point when the ring is operating in turbo mode range.
+  Used when RingVoltageMode = Adaptive.
+  <b>0. no override</b>. Range 0-2000mV.
+  **/
+  UINT16 RingVoltageAdaptive;
+  /**
+  The ring voltage offset applied on top of all other voltage modes. This offset is applied over the entire frequency range.
+  This is a 2's complement number in mV units. <b>Default: 0</b> Range: -1000 to 1000.
+  **/
+  INT16  RingVoltageOffset;
+
+  INT16  GtVoltageOffset;                         ///< The voltage offset applied to GT slice. Valid range from -1000mv to 1000mv: <b>0=Minimal</b>, 1000=Maximum
+  UINT16 GtVoltageOverride;                       ///< The GT voltage override which is applied to the entire range of GT frequencies <b>0=Default</b>
+  UINT16 GtExtraTurboVoltage;                     ///< The adaptive voltage applied during turbo frequencies. Valid range from 0 to 2000mV: <b>0=Minimal</b>, 2000=Maximum
+  INT16  SaVoltageOffset;                         ///< The voltage offset applied to the SA. Valid range from -1000mv to 1000mv: <b>0=Default</b>
+  UINT32 GtPllVoltageOffset     :  6;             ///< GT PLL voltage offset. <b>0: No offset</b>. Range 0-63 in 17.5mv units.
+  UINT32 RingPllVoltageOffset   :  6;             ///< Ring PLL voltage offset. <b>0: No offset</b>. Range 0-63 in 17.5mv units.
+  UINT32 SaPllVoltageOffset     :  6;             ///< System Agent PLL voltage offset. <b>0: No offset</b>. Range 0-63 in 17.5mv units.
+  UINT32 McPllVoltageOffset     :  6;             ///< Memory Controller PLL voltage offset. <b>0: No offset</b>. Range 0-63 in 17.5mv units.
+  UINT32 RsvdBits1              :  8;
+  /**
+  TjMax Offset. Specified value here is clipped by pCode (125 - TjMax Offset) to support TjMax in the range of 62 to 115 deg Celsius.
+  <b> Default: 0 Hardware Defaults </b> Range 10 to 63. 0 = No offset / Keep HW default.
+  **/
+  UINT8  TjMaxOffset;
+  UINT8  RsvdByte2[3];                           //< Reserved for dword alignment
+  /**
+  This service controls Core frequency reduction caused by high package temperatures for processors that
+  implement the Intel Thermal Velocity Boost (TVB) feature. It is required to be disabled for supporting
+  overclocking at frequencies higher than the default max turbo frequency.
+  <b>0: Disables TVB ratio clipping. </b>1: Enables TVB ratio clipping.
+  **/
+  UINT32 TvbRatioClipping       :  1;
+  /**
+  This service controls thermal based voltage optimizations for processors that implement the Intel
+  Thermal Velocity Boost (TVB) feature.
+  0: Disables TVB voltage optimization. <b>1: Enables TVB voltage optimization.</b>
+  **/
+  UINT32 TvbVoltageOptimization :  1;
+  UINT32 RsvdBits2              : 30;
+  /**
+  Defines the per-core HT disable mask where: 1 - Disable selected logical core HT, 0 - is ignored.
+  Input is in HEX and each bit maps to a logical core. Ex. A value of '1F' would disable HT for cores 4,3,2,1 and 0.
+  <b>Default is 0</b>, all cores have HT enabled. Range is 0 - 0x1FF. You can only disable up to MAX_CORE_COUNT - 1.
+  **/
+  UINT16 PerCoreHtDisable;
+  /**
+  Avx2 Voltage Guardband Scale Factor
+  This controls the AVX2 Voltage Guardband Scale factor applied to AVX2 workloads.
+  Valid range is 0-200 in 1/100 units, where a value of 125 would apply a 1.25 scale factor.
+  A value of 0 means no scale factor applied (no change to voltage on AVX commands)
+  A value of 100 applies the default voltage guardband values (1.0 factor).
+  A value > 100 will increase the voltage guardband on AVX2 workloads.
+  A value < 100 will decrease the voltage guardband on AVX2 workloads.
+
+  <b>0. No scale factor applied</b>
+  **/
+  UINT8 Avx2VoltageScaleFactor;
+  /**
+  Avx512 Voltage Guardband Scale Factor
+  This controls the AVX512 Voltage Guardband Scale factor applied to AVX512 workloads.
+  Valid range is 0-200 in 1/100 units, where a value of 125 would apply a 1.25 scale factor.
+  A value of 0 means no scale factor applied (no change to voltage on AVX commands)
+  A value of 100 applies the default voltage guardband values (1.0 factor).
+  A value > 100 will increase the voltage guardband on AVX512 workloads.
+  A value < 100 will decrease the voltage guardband on AVX512 workloads.
+
+  <b>0. No scale factor applied</b>
+  **/
+  UINT8 Avx512VoltageScaleFactor;
+  /**
+  Array used to specifies the Core Voltage Offset applied to the each selected VF Point.
+  This voltage is specified in millivolts.
+  **/
+  INT16  CoreVfPointOffset[CPU_OC_MAX_VF_POINTS];
+  UINT8  RsvdByte3[2];  ///< Just to keep native alignment.
+  /**
+  Array for the each selected VF Point to display the Core Ration.
+  **/
+  UINT8  CoreVfPointRatio[CPU_OC_MAX_VF_POINTS];
+  /**
+  Number of supported Core Voltage & Frequency Point.
+  **/
+  UINT8  CoreVfPointCount;
+  /**
+  Core mask is a bitwise indication of which core should be disabled. Bit 0 - core 0, bit 7 - core 7.
+  **/
+  UINT32 DisableCoreMask;
+  UINT8  PerCoreRatio[CPU_OC_MAX_CORES];
+  /**
+  The VcccIn voltage override.
+  This will override VccIn output voltage level to the voltage value specified.
+  The voltage level is fixed and will not change except on PKG C-states or resets.
+
+  <b>0. no override</b>. Range 0-3000 mV.
+  **/
+  UINT32 VccInVoltageOverride;
+} OVERCLOCKING_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_OVERCLOCKING_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/P2sb/P2sbConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/P2sb/P2sbConfig.h
new file mode 100644
index 0000000000..69271205b1
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/P2sb/P2sbConfig.h
@@ -0,0 +1,34 @@
+/** @file
+  P2sb policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _P2SB_CONFIG_H_
+#define _P2SB_CONFIG_H_
+
+#define P2SB_CONFIG_REVISION 1
+extern EFI_GUID gP2sbConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  This structure contains the policies which are related to P2SB device.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  /**
+    <b>(Test)</b>
+    The sideband MMIO register access to specific ports will be locked
+    before 3rd party code execution. Currently it disables PSFx access.
+    This policy unlocks the sideband MMIO space for those IPs.
+    <b>0: Lock sideband access </b>; 1: Unlock sideband access.
+    NOTE: Do not set this policy "SbAccessUnlock" unless its necessary.
+  **/
+  UINT32    SbAccessUnlock    :  1;
+  UINT32    Rsvdbits          : 31;    ///< Reserved bits
+} PCH_P2SB_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _P2SB_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/PchDmi/PchDmiConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/PchDmi/PchDmiConfig.h
new file mode 100644
index 0000000000..b73108bcfd
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/PchDmi/PchDmiConfig.h
@@ -0,0 +1,44 @@
+/** @file
+  DMI policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_DMI_CONFIG_H_
+#define _PCH_DMI_CONFIG_H_
+
+#define PCH_DMI_CONFIG_REVISION 2
+extern EFI_GUID gPchDmiConfigGuid;
+
+
+#pragma pack (push,1)
+
+
+/**
+ The PCH_DMI_CONFIG block describes the expected configuration of the PCH for DMI.
+   <b>Revision 1</b>:  - Initial version.
+   <b>Revision 2</b>:  - Add OpioRecenter
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header
+
+  UINT32     PwrOptEnable      :  1;    ///< <b>0: Disable</b>; 1: Enable DMI Power Optimizer on PCH side.
+  UINT32     DmiAspmCtrl       :  8;    ///< ASPM configuration on the PCH side of the DMI/OPI Link. Default is <b>PchPcieAspmAutoConfig</b>
+  UINT32     CwbEnable         :  1;    ///< 0: Disable; <b>1: Enable</b> Central Write Buffer feature configurable and enabled by default
+  UINT32     L1RpCtl           :  1;    ///< 0: Disable; <b>1: Enable</b> Allow DMI enter L1 when all root ports are in L1, L0s or link down. Disabled by default.
+  /**
+   When set to TRUE turns on:
+     - L1 State Controller Power Gating
+     - L1 State PHY Data Lane Power Gating
+     - PHY Common Lane Power Gating
+     - Hardware Autonomous Enable
+     - PMC Request Enable and Sleep Enable
+  **/
+  UINT32     DmiPowerReduction :  1;
+  UINT32     OpioRecenter      :  1;    ///< 0: Disable; <b>1: Enable</b> Opio Recentering Disable for Pcie latency
+  UINT32     Rsvdbits          : 19;    ///< Reserved bits
+} PCH_DMI_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _PCH_DMI_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/PcieRp/PchPcieRp/PchPcieRpConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/PcieRp/PchPcieRp/PchPcieRpConfig.h
new file mode 100644
index 0000000000..de086473a9
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/PcieRp/PchPcieRp/PchPcieRpConfig.h
@@ -0,0 +1,368 @@
+/** @file
+  PCH Pcie root port policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_PCIERP_CONFIG_H_
+#define _PCH_PCIERP_CONFIG_H_
+
+#include <PchLimits.h>
+#include <PcieConfig.h>
+#include <ConfigBlock.h>
+
+#define PCIE_RP_CONFIG_REVISION 1
+#define PCIE_RP_PREMEM_CONFIG_REVISION 1
+#define PCIE_RP_DXE_CONFIG_REVISION 1
+
+extern EFI_GUID gPchPcieConfigGuid;
+extern EFI_GUID gPcieRpPreMemConfigGuid;
+
+#pragma pack (push,1)
+
+#define PCIE_LINK_EQ_COEFFICIENTS_MAX 10
+#define PCIE_LINK_EQ_PRESETS_MAX 11
+
+typedef enum {
+  PchPcieOverrideDisabled             = 0,
+  PchPcieL1L2Override                 = 0x01,
+  PchPcieL1SubstatesOverride          = 0x02,
+  PchPcieL1L2AndL1SubstatesOverride   = 0x03,
+  PchPcieLtrOverride                  = 0x04
+} PCH_PCIE_OVERRIDE_CONFIG;
+
+/**
+  PCIe device table entry entry
+
+  The PCIe device table is being used to override PCIe device ASPM settings.
+  To take effect table consisting of such entries must be instelled as PPI
+  on gPchPcieDeviceTablePpiGuid.
+  Last entry VendorId must be 0.
+**/
+typedef struct {
+  UINT16  VendorId;                    ///< The vendor Id of Pci Express card ASPM setting override, 0xFFFF means any Vendor ID
+  UINT16  DeviceId;                    ///< The Device Id of Pci Express card ASPM setting override, 0xFFFF means any Device ID
+  UINT8   RevId;                       ///< The Rev Id of Pci Express card ASPM setting override, 0xFF means all steppings
+  UINT8   BaseClassCode;               ///< The Base Class Code of Pci Express card ASPM setting override, 0xFF means all base class
+  UINT8   SubClassCode;                ///< The Sub Class Code of Pci Express card ASPM setting override, 0xFF means all sub class
+  UINT8   EndPointAspm;                ///< Override device ASPM (see: PCH_PCIE_ASPM_CONTROL)
+                                       ///< Bit 1 must be set in OverrideConfig for this field to take effect
+  UINT16  OverrideConfig;              ///< The override config bitmap (see: PCH_PCIE_OVERRIDE_CONFIG).
+  /**
+    The L1Substates Capability Offset Override. (applicable if bit 2 is set in OverrideConfig)
+    This field can be zero if only the L1 Substate value is going to be override.
+  **/
+  UINT16  L1SubstatesCapOffset;
+  /**
+    L1 Substate Capability Mask. (applicable if bit 2 is set in OverrideConfig)
+    Set to zero then the L1 Substate Capability [3:0] is ignored, and only L1s values are override.
+    Only bit [3:0] are applicable. Other bits are ignored.
+  **/
+  UINT8   L1SubstatesCapMask;
+  /**
+    L1 Substate Port Common Mode Restore Time Override. (applicable if bit 2 is set in OverrideConfig)
+    L1sCommonModeRestoreTime and L1sTpowerOnScale can have a valid value of 0, but not the L1sTpowerOnValue.
+    If L1sTpowerOnValue is zero, all L1sCommonModeRestoreTime, L1sTpowerOnScale, and L1sTpowerOnValue are ignored,
+    and only L1SubstatesCapOffset is override.
+  **/
+  UINT8   L1sCommonModeRestoreTime;
+  /**
+    L1 Substate Port Tpower_on Scale Override. (applicable if bit 2 is set in OverrideConfig)
+    L1sCommonModeRestoreTime and L1sTpowerOnScale can have a valid value of 0, but not the L1sTpowerOnValue.
+    If L1sTpowerOnValue is zero, all L1sCommonModeRestoreTime, L1sTpowerOnScale, and L1sTpowerOnValue are ignored,
+    and only L1SubstatesCapOffset is override.
+  **/
+  UINT8   L1sTpowerOnScale;
+  /**
+    L1 Substate Port Tpower_on Value Override. (applicable if bit 2 is set in OverrideConfig)
+    L1sCommonModeRestoreTime and L1sTpowerOnScale can have a valid value of 0, but not the L1sTpowerOnValue.
+    If L1sTpowerOnValue is zero, all L1sCommonModeRestoreTime, L1sTpowerOnScale, and L1sTpowerOnValue are ignored,
+    and only L1SubstatesCapOffset is override.
+  **/
+  UINT8   L1sTpowerOnValue;
+
+  /**
+    SnoopLatency bit definition
+    Note: All Reserved bits must be set to 0
+
+    BIT[15]     - When set to 1b, indicates that the values in bits 9:0 are valid
+                  When clear values in bits 9:0 will be ignored
+    BITS[14:13] - Reserved
+    BITS[12:10] - Value in bits 9:0 will be multiplied with the scale in these bits
+                  000b - 1 ns
+                  001b - 32 ns
+                  010b - 1024 ns
+                  011b - 32,768 ns
+                  100b - 1,048,576 ns
+                  101b - 33,554,432 ns
+                  110b - Reserved
+                  111b - Reserved
+    BITS[9:0]   - Snoop Latency Value. The value in these bits will be multiplied with
+                  the scale in bits 12:10
+
+    This field takes effect only if bit 3 is set in OverrideConfig.
+  **/
+  UINT16  SnoopLatency;
+  /**
+    NonSnoopLatency bit definition
+    Note: All Reserved bits must be set to 0
+
+    BIT[15]     - When set to 1b, indicates that the values in bits 9:0 are valid
+                  When clear values in bits 9:0 will be ignored
+    BITS[14:13] - Reserved
+    BITS[12:10] - Value in bits 9:0 will be multiplied with the scale in these bits
+                  000b - 1 ns
+                  001b - 32 ns
+                  010b - 1024 ns
+                  011b - 32,768 ns
+                  100b - 1,048,576 ns
+                  101b - 33,554,432 ns
+                  110b - Reserved
+                  111b - Reserved
+    BITS[9:0]   - Non Snoop Latency Value. The value in these bits will be multiplied with
+                  the scale in bits 12:10
+
+    This field takes effect only if bit 3 is set in OverrideConfig.
+  **/
+  UINT16  NonSnoopLatency;
+
+  /**
+    Forces LTR override to be permanent
+    The default way LTR override works is:
+      rootport uses LTR override values provided by BIOS until connected device sends an LTR message, then it will use values from the message
+    This settings allows force override of LTR mechanism. If it's enabled, then:
+      rootport will use LTR override values provided by BIOS forever; LTR messages sent from connected device will be ignored
+  **/
+  UINT8  ForceLtrOverride;
+  UINT8  Reserved[3];
+} PCH_PCIE_DEVICE_OVERRIDE;
+
+///
+/// The values before AutoConfig match the setting of PCI Express Base Specification 1.1, please be careful for adding new feature
+///
+typedef enum {
+  PchPcieAspmDisabled,
+  PchPcieAspmL0s,
+  PchPcieAspmL1,
+  PchPcieAspmL0sL1,
+  PchPcieAspmAutoConfig,
+  PchPcieAspmMax
+} PCH_PCIE_ASPM_CONTROL;
+
+/**
+  Refer to PCH EDS for the PCH implementation values corresponding
+  to below PCI-E spec defined ranges
+**/
+typedef enum {
+  PchPcieL1SubstatesDisabled,
+  PchPcieL1SubstatesL1_1,
+  PchPcieL1SubstatesL1_1_2,
+  PchPcieL1SubstatesMax
+} PCH_PCIE_L1SUBSTATES_CONTROL;
+
+enum PCH_PCIE_MAX_PAYLOAD {
+  PchPcieMaxPayload128 = 0,
+  PchPcieMaxPayload256,
+  PchPcieMaxPayloadMax
+};
+
+typedef enum {
+  PcieLinkHardwareEq = 0,  ///< Hardware is responsible for performing coefficient/preset search.
+  PcieLinkFixedEq          ///< No coefficient/preset search is performed. Fixed values are used.
+} PCIE_LINK_EQ_METHOD;
+
+typedef enum {
+  PcieLinkEqPresetMode = 0,   ///< Use presets during PCIe link equalization
+  PcieLinkEqCoefficientMode   ///< Use coefficients during PCIe link equalization
+} PCIE_LINK_EQ_MODE;
+
+typedef struct {
+  UINT32  PreCursor;    ///< Pre-cursor coefficient
+  UINT32  PostCursor;   ///< Post-cursor coefficient
+} PCIE_LINK_EQ_COEFFICIENTS;
+
+/**
+  PCIe Link EQ Platform Settings
+**/
+typedef struct {
+  UINT8                      PcieLinkEqMethod;               ///< Tells BIOS which link EQ method should be used for this port. Please refer to PCIE_LINK_EQ_METHOD for details of supported methods. Default: PcieLinkHardwareEq
+  UINT8                      PcieLinkEqMode;                 ///< Tells BIOS which mode should be used for PCIe link EQ. Please refer to PCIE_LINK_EQ_MODE for details of supported modes. Default: depends on SoC
+  /**
+    Specifies if BIOS should perform local transmitter override during phase 2 of EQ process.
+    If enabled value in Ph2LocalTransmitterOverridePreset must be valid.
+    <b>0: Disabled</b>; 1: Enabled
+  **/
+  UINT8                      LocalTransmitterOverrideEnable;
+  /**
+    Tells BIOS how many presets/coefficients should be used during link EQ.
+    Entries in the Ph3CoefficientsList or Ph3PresetList(depending on chosen mode) need to be valid up to the number specified in this field.
+  **/
+  UINT8                      Ph3NumberOfPresetsOrCoefficients;
+
+  PCIE_LINK_EQ_COEFFICIENTS  Ph3CoefficientsList[PCIE_LINK_EQ_COEFFICIENTS_MAX];  ///< List of the PCIe coefficients to be used during equalization process. Only valid if PcieLinkEqMode is PcieLinkEqCoefficientMode
+  UINT32                     Ph3PresetList[PCIE_LINK_EQ_PRESETS_MAX];             ///< List of the PCIe preset values to be used during equalization process. Only valid if PcieLinkEqMode is PcieLinkEqPresetMode
+  UINT32                     Ph1DownstreamPortTransmitterPreset;  ///< Specifies the value of the downstream port transmitter preset to be used during phase 1 of the equalization process. Will be applied to all lanes
+  UINT32                     Ph1UpstreamPortTransmitterPreset;    ///< Specifies the value of the upstream port transmitter preset to be used during phase 1 of the equalization process. Will be applied to all lanes
+  /**
+    Specifies the preset that should be used during local transmitter override during phase 2 of EQ process.
+    Used only if LocalTransmitterOverrideEnable is TRUE. Will be applied to all PCIe lanes of the root port.
+    Valid up to the PCIE_LINK_EQ_PRESET_MAX value. <b>Default: 0<\b>
+  **/
+  UINT32                     Ph2LocalTransmitterOverridePreset;
+} PCIE_LINK_EQ_PLATFORM_SETTINGS;
+
+#define PCH_PCIE_NO_SUCH_CLOCK 0xFF
+
+typedef enum {
+  PchClockUsagePchPcie0      = 0,
+  PchClockUsagePchPcie1      = 1,
+  PchClockUsagePchPcie2      = 2,
+  PchClockUsagePchPcie3      = 3,
+  PchClockUsagePchPcie4      = 4,
+  PchClockUsagePchPcie5      = 5,
+  PchClockUsagePchPcie6      = 6,
+  PchClockUsagePchPcie7      = 7,
+  PchClockUsagePchPcie8      = 8,
+  PchClockUsagePchPcie9      = 9,
+  PchClockUsagePchPcie10     = 10,
+  PchClockUsagePchPcie11     = 11,
+  PchClockUsagePchPcie12     = 12,
+  PchClockUsagePchPcie13     = 13,
+  PchClockUsagePchPcie14     = 14,
+  PchClockUsagePchPcie15     = 15,
+  PchClockUsagePchPcie16     = 16,
+  PchClockUsagePchPcie17     = 17,
+  PchClockUsagePchPcie18     = 18,
+  PchClockUsagePchPcie19     = 19,
+  PchClockUsagePchPcie20     = 20,
+  PchClockUsagePchPcie21     = 21,
+  PchClockUsagePchPcie22     = 22,
+  PchClockUsagePchPcie23     = 23,
+  /**
+    Quantity of PCH and CPU PCIe ports, as well as their encoding in this enum, may change between
+    silicon generations and series. Do not assume that PCH port 0 will be always encoded by 0.
+    Instead, it is recommended to use (PchClockUsagePchPcie0 + PchPortIndex) style to be forward-compatible
+  **/
+  PchClockUsageCpuPcie0      = 0x40,
+  PchClockUsageCpuPcie1      = 0x41,
+  PchClockUsageCpuPcie2      = 0x42,
+  PchClockUsageCpuPcie3      = 0x43,
+
+  PchClockUsageLan           = 0x70,
+  PchClockUsageUnspecified   = 0x80, ///< In use for a purpose not listed above
+  PchClockUsageNotUsed       = 0xFF
+} PCH_PCIE_CLOCK_USAGE;
+
+/**
+  PCH_PCIE_CLOCK describes PCIe source clock generated by PCH.
+**/
+typedef struct {
+  UINT8   Usage;        ///< Purpose of given clock (see PCH_PCIE_CLOCK_USAGE). Default: Unused, 0xFF
+  UINT8   ClkReq;       ///< ClkSrc - ClkReq mapping. Default: 1:1 mapping with Clock numbers
+  UINT8   RsvdBytes[2]; ///< Reserved byte
+} PCH_PCIE_CLOCK;
+
+/**
+  The PCH_PCI_EXPRESS_ROOT_PORT_CONFIG describe the feature and capability of each PCH PCIe root port.
+**/
+typedef struct {
+  PCIE_ROOT_PORT_COMMON_CONFIG  PcieRpCommonConfig; ///an instance of Pcie Common Config
+  UINT8  ExtSync;              ///< Indicate whether the extended synch is enabled. <b>0: Disable</b>; 1: Enable.
+  //
+  // Error handlings
+  //
+  UINT8  SystemErrorEnable;    ///< Indicate whether the System Error is enabled. <b>0: Disable</b>; 1: Enable.
+  /**
+    The Multiple VC (MVC) supports hardware to avoid HoQ block for latency sensitive TC.
+    Currently it is only applicable to Root Ports with 2pX4 port configuration with 2 VCs,or
+    DMI port configuration with 3 VCs. For Root Ports 2pX4 configuration, two RPs (RP0,
+    RP2) shall support two PCIe VCs (VC0 & VC1) and the other RPs (RP1, RP3) shall be
+    disabled.
+    <b>0: Disable</b>; 1: Enable
+  **/
+  UINT8  MvcEnabled;
+  /**
+    Virtual Pin Port is industry standard introduced to PCIe Hot Plug support in systems
+    when GPIO pins expansion is needed. It is server specific feature.
+    <b>0x00: Default</b>; 0xFF: Disabled
+  **/
+  UINT8   VppPort;
+  UINT8   VppAddress;                               ///< PCIe Hot Plug VPP SMBus Address. Default is zero.
+  UINT8   RsvdBytes0[3];                            ///< Reserved bytes
+} PCH_PCIE_ROOT_PORT_CONFIG;
+
+/**
+  The PCH_PCIE_CONFIG block describes the expected configuration of the PCH PCI Express controllers
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  ///
+  /// These members describe the configuration of each PCH PCIe root port.
+  ///
+  PCIE_COMMON_CONFIG                PcieCommonConfig;
+  PCH_PCIE_ROOT_PORT_CONFIG         RootPort[PCH_MAX_PCIE_ROOT_PORTS];
+  PCIE_LINK_EQ_PLATFORM_SETTINGS    PcieLinkEqPlatformSettings;  ///< Global PCIe link EQ settings that BIOS will use during PCIe link EQ for every port.
+  ///
+  /// <b>0: Use project default equalization settings</b>; 1: Use equalization settings from PcieLinkEqPlatformSettings
+  ///
+  UINT8  OverrideEqualizationDefaults;
+  ///
+  /// <b>(Test)</b> This member describes whether PCIE root port Port 8xh Decode is enabled. <b>0: Disable</b>; 1: Enable.
+  ///
+  UINT8  EnablePort8xhDecode;
+  ///
+  /// <b>(Test)</b> The Index of PCIe Port that is selected for Port8xh Decode (0 Based)
+  ///
+  UINT8  PchPciePort8xhDecodePortIndex;
+  UINT8  RsvdBytes0[1];
+} PCH_PCIE_CONFIG;
+
+/**
+  The PCH_PCIE_RP_PREMEM_CONFIG block describes early configuration of the PCH PCI Express controllers
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                                ///< Config Block Header
+  /**
+    Root Port enabling mask.
+    Bit0 presents RP1, Bit1 presents RP2, and so on.
+    0: Disable; <b>1: Enable</b>.
+  **/
+  UINT32                RpEnabledMask;
+  /// Configuration of PCIe source clocks
+  ///
+  PCH_PCIE_CLOCK        PcieClock[PCH_MAX_PCIE_CLOCKS];
+
+  /**
+    Per Controller Bifurcation Configuration
+    <b>0: Disabled</b>; 1: 4x1; 2: 1x2_2x1; 3: 2x2; 4: 1x4; 5: 4x2; 6: 1x4_2x2; 7: 2x2_1x4; 8: 2x4; 9: 1x8 (see: PCIE_BIFURCATION_CONFIG)
+  **/
+  UINT8                 Bifurcation[PCH_MAX_PCIE_CONTROLLERS];
+  UINT8                 Rsvd4[(4 - PCH_MAX_PCIE_CONTROLLERS % 4) % 4];
+} PCH_PCIE_RP_PREMEM_CONFIG;
+
+/**
+  The PCIE_RP_DXE_CONFIG block describes the expected configuration of the PCH PCI Express controllers in DXE phase
+
+  <b>Revision 1</b>:
+  - Init version
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER      Header;                     ///< Config Block Header
+
+  /**
+    PCIe device override table
+    The PCIe device table is being used to override PCIe device ASPM settings.
+    And it's only used in DXE phase.
+    Please refer to PCH_PCIE_DEVICE_OVERRIDE structure for the table.
+    Last entry VendorId must be 0.
+  **/
+  PCH_PCIE_DEVICE_OVERRIDE    *PcieDeviceOverrideTablePtr;
+} PCIE_RP_DXE_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _PCH_PCIERP_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/PcieRp/PcieConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/PcieRp/PcieConfig.h
new file mode 100644
index 0000000000..4c5b075334
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/PcieRp/PcieConfig.h
@@ -0,0 +1,217 @@
+/** @file
+  PCIe Config Block
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCIE_CONFIG_H_
+#define _PCIE_CONFIG_H_
+#include <CpuPcieInfo.h>
+
+#define PCIE_CONFIG_REVISION  3
+/*
+<b>Revision 2< / b>:
+FomsCp - Deprecated
+<b>Revision 3< / b>:
+Added PCIE_EQ_PARAM  HwEqGen3CoeffList for all CPU_PCIE_MAX_ROOT_PORTS
+Added PCIE_EQ_PARAM  HwEqGen4CoeffList for all CPU_PCIE_MAX_ROOT_PORTS
+Added PCIE_EQ_PARAM  HwEqGen5CoeffList for all CPU_PCIE_MAX_ROOT_PORTS
+*/
+
+extern EFI_GUID gPcieConfigGuid;
+
+#pragma pack (push,1)
+
+enum PCIE_COMPLETION_TIMEOUT {
+  PcieCompletionTO_Default,
+  PcieCompletionTO_50_100us,
+  PcieCompletionTO_1_10ms,
+  PcieCompletionTO_16_55ms,
+  PcieCompletionTO_65_210ms,
+  PcieCompletionTO_260_900ms,
+  PcieCompletionTO_1_3P5s,
+  PcieCompletionTO_4_13s,
+  PcieCompletionTO_17_64s,
+  PcieCompletionTO_Disabled
+};
+
+enum PCIE_SPEED {
+  PcieAuto,
+  PcieGen1,
+  PcieGen2,
+  PcieGen3,
+  PcieGen4
+};
+
+/**
+  Represent lane specific PCIe Gen3 equalization parameters.
+**/
+typedef struct {
+  UINT8   Cm;                 ///< Coefficient C-1
+  UINT8   Cp;                 ///< Coefficient C+1
+  UINT8   Rsvd0[2];           ///< Reserved bytes
+} PCIE_EQ_PARAM;
+
+typedef struct {
+  UINT16  LtrMaxSnoopLatency;                     ///< <b>(Test)</b> Latency Tolerance Reporting, Max Snoop Latency.
+  UINT16  LtrMaxNoSnoopLatency;                   ///< <b>(Test)</b> Latency Tolerance Reporting, Max Non-Snoop Latency.
+  UINT8   SnoopLatencyOverrideMode;               ///< <b>(Test)</b> Latency Tolerance Reporting, Snoop Latency Override Mode.
+  UINT8   SnoopLatencyOverrideMultiplier;         ///< <b>(Test)</b> Latency Tolerance Reporting, Snoop Latency Override Multiplier.
+  UINT16  SnoopLatencyOverrideValue;              ///< <b>(Test)</b> Latency Tolerance Reporting, Snoop Latency Override Value.
+  UINT8   NonSnoopLatencyOverrideMode;            ///< <b>(Test)</b> Latency Tolerance Reporting, Non-Snoop Latency Override Mode.
+  UINT8   NonSnoopLatencyOverrideMultiplier;      ///< <b>(Test)</b> Latency Tolerance Reporting, Non-Snoop Latency Override Multiplier.
+  UINT16  NonSnoopLatencyOverrideValue;           ///< <b>(Test)</b> Latency Tolerance Reporting, Non-Snoop Latency Override Value.
+  UINT8   LtrConfigLock;                          ///< <b>0: Disable</b>; 1: Enable.
+  UINT8   ForceLtrOverride;
+  UINT16  RsvdByte1;
+} PCIE_LTR_CONFIG;
+
+
+/**
+  Specifies the form factor that the slot
+  implements. For custom form factors that
+  do not require any special handling please
+  set PcieFormFactorOther.
+**/
+typedef enum {
+  PcieFormFactorOther = 0,
+  PcieFormFactorCem,
+  PcieFormFactorMiniPci,
+  PcieFormFactorM2,
+  PcieFormFactorOcuLink,
+  PcieFormFactorExpressModule, // Also known as Server IO module(SIOM)
+  PcieFormFactorExpressCard,
+  PcieFormFactorU2 // Also known as SF-8639
+} PCIE_FORM_FACTOR;
+
+//Note: This structure will be expanded to hold all common PCIe policies between SA and PCH RootPort
+typedef struct {
+  UINT32  HotPlug                         :  1;   ///< Indicate whether the root port is hot plug available. <b>0: Disable</b>; 1: Enable.
+  UINT32  PmSci                           :  1;   ///< Indicate whether the root port power manager SCI is enabled. 0: Disable; <b>1: Enable</b>.
+  UINT32  TransmitterHalfSwing            :  1;   ///< Indicate whether the Transmitter Half Swing is enabled. <b>0: Disable</b>; 1: Enable.
+  UINT32  AcsEnabled                      :  1;   ///< Indicate whether the ACS is enabled. 0: Disable; <b>1: Enable</b>.
+  //
+  // Error handlings
+  //
+  UINT32  AdvancedErrorReporting          :  1;   ///< Indicate whether the Advanced Error Reporting is enabled. <b>0: Disable</b>; 1: Enable.
+  UINT32  UnsupportedRequestReport        :  1;   ///< Indicate whether the Unsupported Request Report is enabled. <b>0: Disable</b>; 1: Enable.
+  UINT32  FatalErrorReport                :  1;   ///< Indicate whether the Fatal Error Report is enabled. <b>0: Disable</b>; 1: Enable.
+  UINT32  NoFatalErrorReport              :  1;   ///< Indicate whether the No Fatal Error Report is enabled. <b>0: Disable</b>; 1: Enable.
+  UINT32  CorrectableErrorReport          :  1;   ///< Indicate whether the Correctable Error Report is enabled. <b>0: Disable</b>; 1: Enable.
+  UINT32  SystemErrorOnFatalError         :  1;   ///< Indicate whether the System Error on Fatal Error is enabled. <b>0: Disable</b>; 1: Enable.
+  UINT32  SystemErrorOnNonFatalError      :  1;   ///< Indicate whether the System Error on Non Fatal Error is enabled. <b>0: Disable</b>; 1: Enable.
+  UINT32  SystemErrorOnCorrectableError   :  1;   ///< Indicate whether the System Error on Correctable Error is enabled. <b>0: Disable</b>; 1: Enable.
+  /**
+    Max Payload Size supported, Default <b>128B</b>, see enum CPU_PCIE_MAX_PAYLOAD
+    Changes Max Payload Size Supported field in Device Capabilities of the root port.
+  **/
+  UINT32  MaxPayload                      :  2;
+  UINT32  DpcEnabled                      :  1;   ///< Downstream Port Containment. 0: Disable; <b>1: Enable</b>
+  UINT32  RpDpcExtensionsEnabled          :  1;   ///< RP Extensions for Downstream Port Containment. 0: Disable; <b>1: Enable</b>
+  /**
+    Indicates how this root port is connected to endpoint. 0: built-in device; <b>1: slot</b>
+    Built-in is incompatible with hotplug-capable ports.
+  **/
+  UINT32  SlotImplemented                 :  1;
+  UINT32  PtmEnabled                      :  1;   ///< Enables PTM capability
+  UINT32  SlotPowerLimitScale             :  2;   ///< <b>(Test)</b> Specifies scale used for slot power limit value. Leave as 0 to set to default. Default is <b>zero</b>.
+  UINT32  SlotPowerLimitValue             : 12;   //< <b>(Test)</b> Specifies upper limit on power supplies by slot. Leave as 0 to set to default. Default is <b>zero</b>.
+  /**
+    Probe CLKREQ# signal before enabling CLKREQ# based power management.
+    Conforming device shall hold CLKREQ# low until CPM is enabled. This feature attempts
+    to verify CLKREQ# signal is connected by testing pad state before enabling CPM.
+    In particular this helps to avoid issues with open-ended PCIe slots.
+    This is only applicable to non hot-plug ports.
+    <b>0: Disable</b>; 1: Enable.
+  **/
+  UINT32  ClkReqDetect                    :  1;
+  /**
+    Set if the slot supports manually operated retention latch.
+  **/
+  UINT32  MrlSensorPresent                :  1;
+  UINT32  RelaxedOrder                    :  1;
+  UINT32  NoSnoop                         :  1;
+  UINT32  RsvdBits0                       : 28;   ///< Reserved bits.
+  /**
+    PCIe Gen3 Equalization Phase 3 Method (see CPU_PCIE_EQ_METHOD).
+    0: DEPRECATED, hardware equalization; <b>1: hardware equalization</b>; 4: Fixed Coefficients
+  **/
+  UINT8   Gen3EqPh3Method;
+  UINT8   PhysicalSlotNumber;                     ///< Indicates the slot number for the root port. Default is the value as root port index.
+  UINT8   CompletionTimeout;                      ///< The completion timeout configuration of the root port (see: CPU_PCIE_COMPLETION_TIMEOUT). Default is <b>PchPcieCompletionTO_Default</b>.
+  //
+  // Power Management
+  //
+  UINT8   Aspm;                                   ///< The ASPM configuration of the root port (see: CPU_PCIE_ASPM_CONTROL). Default is <b>PchPcieAspmAutoConfig</b>.
+  UINT8   L1Substates;                            ///< The L1 Substates configuration of the root port (see: CPU_PCIE_L1SUBSTATES_CONTROL). Default is <b>PchPcieL1SubstatesL1_1_2</b>.
+  UINT8   LtrEnable;                              ///< Latency Tolerance Reporting Mechanism. <b>0: Disable</b>; 1: Enable.
+  UINT8   EnableCpm;                              ///< Enables Clock Power Management; even if disabled, CLKREQ# signal can still be controlled by L1 PM substates mechanism
+  UINT8   PcieSpeed;                              ///< Contains speed of PCIe bus (see: PCIE_SPEED)
+  /**
+  <b>(Test)</b>
+  Forces LTR override to be permanent
+  The default way LTR override works is:
+  rootport uses LTR override values provided by BIOS until connected device sends an LTR message, then it will use values from the message
+  This settings allows force override of LTR mechanism. If it's enabled, then:
+  rootport will use LTR override values provided by BIOS forever; LTR messages sent from connected device will be ignored
+  **/
+  PCIE_LTR_CONFIG               PcieRpLtrConfig;            ///< <b>(Test)</b> Latency Tolerance Reporting Policies including LTR limit and Override
+    /**
+    The number of milliseconds reference code will wait for link to exit Detect state for enabled ports
+    before assuming there is no device and potentially disabling the port.
+    It's assumed that the link will exit detect state before root port initialization (sufficient time
+    elapsed since PLTRST de-assertion) therefore default timeout is zero. However this might be useful
+    if device power-up seqence is controlled by BIOS or a specific device requires more time to detect.
+    In case of non-common clock enabled the default timout is 15ms.
+    <b>Default: 0</b>
+  **/
+  UINT16  DetectTimeoutMs;
+  UINT8   FormFactor; // Please check PCIE_FORM_FACTOR for supported values
+  UINT8   Reserved;
+} PCIE_ROOT_PORT_COMMON_CONFIG;
+
+/**
+  PCIe Common Config
+  @note This structure will be expanded to hold all common PCIe policies between SA and PCH
+**/
+typedef struct {
+  ///
+  /// This member describes whether Peer Memory Writes are enabled on the platform. <b>0: Disable</b>; 1: Enable.
+  ///
+  UINT32  EnablePeerMemoryWrite          :  1;
+  /**
+    RpFunctionSwap allows BIOS to use root port function number swapping when root port of function 0 is disabled.
+    A PCIE device can have higher functions only when Function0 exists. To satisfy this requirement,
+    BIOS will always enable Function0 of a device that contains more than 0 enabled root ports.
+    - <b>Enabled: One of enabled root ports get assigned to Function0.</b>
+      This offers no guarantee that any particular root port will be available at a specific DevNr:FuncNr location
+    - Disabled: Root port that corresponds to Function0 will be kept visible even though it might be not used.
+      That way rootport - to - DevNr:FuncNr assignment is constant. This option will impact ports 1, 9, 17.
+      NOTE: This option will not work if ports 1, 9, 17 are fused or configured for RST PCIe storage or disabled through policy
+            In other words, it only affects ports that would become hidden because they have no device connected.
+      NOTE: Disabling function swap may have adverse impact on power management. This option should ONLY
+            be used when each one of root ports 1, 9, 17:
+        - is configured as PCIe and has correctly configured ClkReq signal, or
+        - does not own any mPhy lanes (they are configured as SATA or USB)
+  **/
+  UINT32  RpFunctionSwap                   :  1;
+  /**
+    Compliance Test Mode shall be enabled when using Compliance Load Board.
+    <b>0: Disable</b>, 1: Enable
+  **/
+  UINT32  ComplianceTestMode               :  1;
+  UINT32  RsvdBits0                        : 29;   ///< Reserved bits
+  ///
+  /// List of coefficients used during equalization (applicable to both software and hardware EQ)
+  /// Deprecated Policy
+  ///
+  PCIE_EQ_PARAM                    HwEqGen3CoeffList[PCIE_HWEQ_COEFFS_MAX];
+} PCIE_COMMON_CONFIG;
+
+typedef struct {
+  PCIE_EQ_PARAM                            HwEqGen3CoeffList[CPU_PCIE_MAX_ROOT_PORTS][PCIE_HWEQ_COEFFS_MAX];
+  PCIE_EQ_PARAM                            HwEqGen4CoeffList[CPU_PCIE_MAX_ROOT_PORTS][PCIE_HWEQ_COEFFS_MAX];
+} PCIE_COMMON_CONFIG2;
+
+#pragma pack (pop)
+#endif // _PCIE_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Pmc/AdrConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Pmc/AdrConfig.h
new file mode 100644
index 0000000000..5c7811823d
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Pmc/AdrConfig.h
@@ -0,0 +1,86 @@
+/** @file
+  ADR policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ADR_CONFIG_H_
+#define _ADR_CONFIG_H_
+
+#include <ConfigBlock.h>
+
+#define ADR_CONFIG_REVISION 1
+extern EFI_GUID gAdrConfigGuid;
+
+#pragma pack (push,1)
+
+typedef enum {
+  AdrScale1us,
+  AdrScale10us,
+  AdrScale100us,
+  AdrScale1ms,
+  AdrScale10ms,
+  AdrScale100ms,
+  AdrScale1s,
+  AdrScale10s
+} ADR_TIMER_SCALE;
+
+/**
+  ADR Source Enable
+**/
+typedef union {
+  struct {
+    UINT32 Reserved1           : 1;
+    UINT32 AdrSrcPbo           : 1;
+    UINT32 AdrSrcPmcUncErr     : 1;
+    UINT32 AdrSrcPchThrm       : 1;
+    UINT32 AdrSrcMePbo         : 1;
+    UINT32 AdrSrcCpuThrm       : 1;
+    UINT32 AdrSrcMegbl         : 1;
+    UINT32 AdrSrcLtReset       : 1;
+    UINT32 AdrSrcPmcWdt        : 1;
+    UINT32 AdrSrcMeWdt         : 1;
+    UINT32 AdrSrcPmcFw         : 1;
+    UINT32 AdrSrcPchpwrFlr     : 1;
+    UINT32 AdrSrcSyspwrFlr     : 1;
+    UINT32 Reserved2           : 1;
+    UINT32 AdrSrcMiaUxsErr     : 1;
+    UINT32 AdrSrcMiaUxErr      : 1;
+    UINT32 AdrSrcCpuThrmWdt    : 1;
+    UINT32 AdrSrcMeUncErr      : 1;
+    UINT32 AdrSrcAdrGpio       : 1;
+    UINT32 AdrSrcOcwdtNoicc    : 1;
+    UINT32 AdrSrcOcwdtIcc      : 1;
+    UINT32 AdrSrcCseHecUncErr  : 1;
+    UINT32 AdrSrcPmcSramUncErr : 1;
+    UINT32 AdrSrcPmcIromParity : 1;
+    UINT32 AdrSrcPmcRfFusaErr  : 1;
+    UINT32 Reserved3           : 4;
+    UINT32 AdrSrcPpbrParityErr : 1;
+    UINT32 Reserved4           : 2;
+  } Field;
+  UINT32 Value;
+} ADR_SOURCE_ENABLE;
+
+/**
+  ADR Configuration
+  <b>Revision 1</b>:  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header
+  UINT32        AdrEn                  : 2; ///< Determine if Adr is enabled - 0: PLATFORM_POR, 1: FORCE_ENABLE, 2: FORCE_DISABLE
+  UINT32        AdrTimerEn             : 2; ///< Determine if Adr timer options are enabled - 0: PLATFORM_POR, 1: FORCE_ENABLE, 2: FORCE_DISABLE
+  UINT32        AdrTimer1Val           : 2; ///< Determines the Timeout value used for the ADR timer 1. A value of zero bypasses the timer
+  UINT32        AdrMultiplier1Val      : 8; ///< Specifies the tick frequency upon which the timer 1 will increment. ADR_TIMER_SCALE should be used to encode values
+  UINT32        AdrTimer2Val           : 8; ///< Determines the Timeout value used for the ADR timer 2. A value of zero bypasses the timer
+  UINT32        AdrMultiplier2Val      : 8; ///< Specifies the tick frequency upon which the timer 2 will increment. ADR_TIMER_SCALE should be used to encode values
+  UINT32        AdrHostPartitionReset  : 2; ///< Determine if Host Partition Reset is enabled - 0: PLATFORM_POR, 1: FORCE_ENABLE, 2: FORCE_DISABLE
+  UINT32        AdrSrcOverride         : 1; ///< Check if default ADR sources will be overriten with custom 0: Not overwritten, 1: Overwritten
+  UINT32        ReservedBits           : 31;
+  ADR_SOURCE_ENABLE   AdrSrcSel;            ///< Determine which ADR sources are enabled - 0: Enabled, 1: Disabled
+} ADR_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _ADR_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Pmc/PmConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Pmc/PmConfig.h
new file mode 100644
index 0000000000..2f8e19b50b
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Pmc/PmConfig.h
@@ -0,0 +1,391 @@
+/** @file
+  Power Management policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PM_CONFIG_H_
+#define _PM_CONFIG_H_
+
+#include <ConfigBlock.h>
+
+#define PM_CONFIG_REVISION 2
+extern EFI_GUID gPmConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  This structure allows to customize PCH wake up capability from S5 or DeepSx by WOL, LAN, PCIE wake events.
+**/
+typedef struct {
+  /**
+    Corresponds to the PME_B0_S5_DIS bit in the General PM Configuration B (GEN_PMCON_B) register.
+    When set to 1, this bit blocks wake events from PME_B0_STS in S5, regardless of the state of PME_B0_EN.
+    When cleared (default), wake events from PME_B0_STS are allowed in S5 if PME_B0_EN = 1. <b>0: Disable</b>; 1: Enable.
+  **/
+  UINT32  PmeB0S5Dis         :  1;
+  UINT32  WolEnableOverride  :  1;      ///< Corresponds to the "WOL Enable Override" bit in the General PM Configuration B (GEN_PMCON_B) register. 0: Disable; <b>1: Enable</b>.
+  UINT32  PcieWakeFromDeepSx :  1;      ///< Determine if enable PCIe to wake from deep Sx. <b>0: Disable</b>; 1: Enable.
+  UINT32  WoWlanEnable       :  1;      ///< Determine if WLAN wake from Sx, corresponds to the "HOST_WLAN_PP_EN" bit in the PWRM_CFG3 register. <b>0: Disable</b>; 1: Enable.
+  UINT32  WoWlanDeepSxEnable :  1;      ///< Determine if WLAN wake from DeepSx, corresponds to the "DSX_WLAN_PP_EN" bit in the PWRM_CFG3 register. <b>0: Disable</b>; 1: Enable.
+  UINT32  LanWakeFromDeepSx  :  1;      ///< Determine if enable LAN to wake from deep Sx. 0: Disable; <b>1: Enable</b>.
+  UINT32  RsvdBits0          : 26;
+} PCH_WAKE_CONFIG;
+
+typedef enum {
+  PchDeepSxPolDisable,
+  PchDpS5BatteryEn,
+  PchDpS5AlwaysEn,
+  PchDpS4S5BatteryEn,
+  PchDpS4S5AlwaysEn,
+  PchDpS3S4S5BatteryEn,
+  PchDpS3S4S5AlwaysEn
+} PCH_DEEP_SX_CONFIG;
+
+typedef enum {
+  PchSlpS360us = 1,
+  PchSlpS31ms,
+  PchSlpS350ms,
+  PchSlpS32s
+} PCH_SLP_S3_MIN_ASSERT;
+
+typedef enum {
+  PchSlpS4PchTime,     ///< The time defined in PCH EDS Power Sequencing and Reset Signal Timings table
+  PchSlpS41s,
+  PchSlpS42s,
+  PchSlpS43s,
+  PchSlpS44s
+} PCH_SLP_S4_MIN_ASSERT;
+
+typedef enum {
+  PchSlpSus0ms = 1,
+  PchSlpSus500ms,
+  PchSlpSus1s,
+  PchSlpSus4s,
+} PCH_SLP_SUS_MIN_ASSERT;
+
+typedef enum {
+  PchSlpA0ms = 1,
+  PchSlpA4s,
+  PchSlpA98ms,
+  PchSlpA2s,
+} PCH_SLP_A_MIN_ASSERT;
+
+typedef enum {
+  S0ixDisQNoChange,
+  S0ixDisQDciOob,
+  S0ixDisQUsb2Dbc,
+  S0ixDisQMax,
+} S0IX_DISQ_PROBE_TYPE;
+
+/**
+  Low Power Mode Enable config.
+  Used to configure if respective S0i2/3 sub-states are to be supported
+  by the platform. Each bit corresponds to one LPM state - LPMx->BITx.
+  Some sub-states will require external FETs controlled by EXT_PWR_GATE#/EXT_PWR_GATE2# pins
+  to gate v1p05-PHY or v1p05-IS supplies
+**/
+typedef union {
+  struct {
+    UINT32  S0i2p0En     : 1;        ///< LPM0 - S0i2.0 Enable
+    UINT32  S0i2p1En     : 1;        ///< LPM1 - S0i2.1 Enable
+    /**
+      LPM2 - S0i2.2 Enable.
+      Requires EXT_PWR_GATE# controlled FET to gate v1p05 PHY.
+      Refer to V1p05PhyExtFetControlEn.
+    **/
+    UINT32  S0i2p2En     : 1;
+    UINT32  S0i3p0En     : 1;        ///< LPM3 - S0i3.0 Enable
+    UINT32  S0i3p1En     : 1;        ///< LPM4 - S0i3.1 Enable
+    UINT32  S0i3p2En     : 1;        ///< LPM5 - S0i3.2 Enable
+    /**
+      LPM5 - S0i3.3 Enable.
+      Requires EXT_PWR_GATE# controlled FET to gate v1p05 PHY.
+      Refer to V1p05PhyExtFetControlEn.
+    **/
+    UINT32  S0i3p3En     : 1;
+    /**
+      LPM7 - S0i3.4 Enable.
+      Requires EXT_PWR_GATE2# controlled FET to gate v1p05-SRAM/ISCLK.
+      Refer to V1p05IsExtFetControlEn.
+    **/
+    UINT32  S0i3p4En     : 1;
+    UINT32  Reserved     : 24;       ///< Reserved
+  } Field;
+  UINT32  Val;
+} PMC_LPM_S0IX_SUB_STATE_EN;
+
+/**
+  Description of Global Reset Trigger/Event Mask register
+**/
+typedef union {
+  struct {
+    UINT32 Reserved1     : 1;
+    UINT32 Pbo           : 1;
+    UINT32 PmcUncErr     : 1;
+    UINT32 PchThrm       : 1;
+    UINT32 MePbo         : 1;
+    UINT32 CpuThrm       : 1;
+    UINT32 Megbl         : 1;
+    UINT32 LtReset       : 1;
+    UINT32 PmcWdt        : 1;
+    UINT32 MeWdt         : 1;
+    UINT32 PmcFw         : 1;
+    UINT32 PchpwrFlr     : 1;
+    UINT32 SyspwrFlr     : 1;
+    UINT32 Reserved2     : 1;
+    UINT32 MiaUxsErr     : 1;
+    UINT32 MiaUxErr      : 1;
+    UINT32 CpuThrmWdt    : 1;
+    UINT32 MeUncErr      : 1;
+    UINT32 AdrGpio       : 1;
+    UINT32 OcwdtNoicc    : 1;
+    UINT32 OcwdtIcc      : 1;
+    UINT32 CseHecUncErr  : 1;
+    UINT32 PmcSramUncErr : 1;
+    UINT32 PmcIromParity : 1;
+    UINT32 PmcRfFusaErr  : 1;
+    UINT32 Reserved3     : 4;
+    UINT32 PpbrParityErr : 1;
+    UINT32 Reserved4     : 2;
+  } Field;
+  UINT32 Value;
+} PMC_GLOBAL_RESET_MASK;
+
+/**
+  The PCH_PM_CONFIG block describes expected miscellaneous power management settings.
+  The PowerResetStatusClear field would clear the Power/Reset status bits, please
+  set the bits if you want PCH Init driver to clear it, if you want to check the
+  status later then clear the bits.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>
+  - Added C10DynamicThresholdAdjustment
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER     Header;                           ///< Config Block Header
+
+  PCH_WAKE_CONFIG         WakeConfig;                       ///< Specify Wake Policy
+  UINT32                  PchDeepSxPol       :  4;          ///< Deep Sx Policy. Refer to PCH_DEEP_SX_CONFIG for each value. Default is <b>PchDeepSxPolDisable</b>.
+  UINT32                  PchSlpS3MinAssert  :  4;          ///< SLP_S3 Minimum Assertion Width Policy. Refer to PCH_SLP_S3_MIN_ASSERT for each value. Default is <b>PchSlpS350ms</b>.
+  UINT32                  PchSlpS4MinAssert  :  4;          ///< SLP_S4 Minimum Assertion Width Policy. Refer to PCH_SLP_S4_MIN_ASSERT for each value. Default is <b>PchSlpS44s</b>.
+  UINT32                  PchSlpSusMinAssert :  4;          ///< SLP_SUS Minimum Assertion Width Policy. Refer to PCH_SLP_SUS_MIN_ASSERT for each value. Default is <b>PchSlpSus4s</b>.
+  UINT32                  PchSlpAMinAssert   :  4;          ///< SLP_A Minimum Assertion Width Policy. Refer to PCH_SLP_A_MIN_ASSERT for each value. Default is <b>PchSlpA2s</b>.
+  UINT32                  RsvdBits0          : 12;
+  /**
+    This member describes whether or not the LPC ClockRun feature of PCH should
+    be enabled. <b>0: Disable</b>; 1: Enable
+  **/
+  UINT32                  SlpStrchSusUp        :  1;        ///< <b>0: Disable</b>; 1: Enable SLP_X Stretching After SUS Well Power Up
+  /**
+    Enable/Disable SLP_LAN# Low on DC Power. 0: Disable; <b>1: Enable</b>.
+    Configure On DC PHY Power Diable according to policy SlpLanLowDc.
+    When this is enabled, SLP_LAN# will be driven low when ACPRESENT is low.
+    This indicates that LAN PHY should be powered off on battery mode.
+    This will override the DC_PP_DIS setting by WolEnableOverride.
+  **/
+  UINT32                  SlpLanLowDc          :  1;
+  /**
+    PCH power button override period.
+    000b-4s, 001b-6s, 010b-8s, 011b-10s, 100b-12s, 101b-14s
+    <b>Default is 0: 4s</b>
+  **/
+  UINT32                  PwrBtnOverridePeriod :  3;
+  /**
+    <b>(Test)</b>
+    Disable/Enable PCH to CPU enery report feature. <b>0: Disable</b>; 1: Enable.
+    Enery Report is must have feature. Wihtout Energy Report, the performance report
+    by workloads/benchmarks will be unrealistic because PCH's energy is not being accounted
+    in power/performance management algorithm.
+    If for some reason PCH energy report is too high, which forces CPU to try to reduce
+    its power by throttling, then it could try to disable Energy Report to do first debug.
+    This might be due to energy scaling factors are not correct or the LPM settings are not
+    kicking in.
+  **/
+  UINT32                  DisableEnergyReport  :  1;
+  /**
+    When set to Disable, PCH will internal pull down AC_PRESENT in deep SX and during G3 exit.
+    When set to Enable, PCH will not pull down AC_PRESENT.
+    This setting is ignored when DeepSx is not supported.
+    Default is <b>0:Disable</b>
+  **/
+  UINT32                  DisableDsxAcPresentPulldown  :  1;
+  /**
+    Power button native mode disable.
+    While FALSE, the PMC's power button logic will act upon the input value from the GPIO unit, as normal.
+    While TRUE, this will result in the PMC logic constantly seeing the power button as de-asserted.
+    <b>Default is FALSE.</b>
+  **/
+  UINT32                  DisableNativePowerButton     :  1;
+  UINT32                  MeWakeSts                    :  1;     ///< Clear the ME_WAKE_STS bit in the Power and Reset Status (PRSTS) register. 0: Disable; <b>1: Enable</b>.
+  UINT32                  WolOvrWkSts                  :  1;     ///< Clear the WOL_OVR_WK_STS bit in the Power and Reset Status (PRSTS) register. 0: Disable; <b>1: Enable</b>.
+  /*
+    Set true to enable TCO timer.
+    When FALSE, it disables PCH ACPI timer, and stops TCO timer.
+    @note: This will have significant power impact when it's enabled.
+    If TCO timer is disabled, uCode ACPI timer emulation must be enabled,
+    and WDAT table must not be exposed to the OS.
+    <b>0: Disable</b>, 1: Enable
+  */
+  UINT32                  EnableTcoTimer               : 1;
+  /*
+    When VRAlert# feature pin is enabled and its state is '0',
+    the PMC requests throttling to a T3 Tstate to the PCH throttling unit.
+    <b>0: Disable</b>; 1: Enable.
+  */
+  UINT32                  VrAlert                      : 1;
+  /**
+    Decide if PS_ON is to be enabled. This is available on desktop only.
+    PS_ON is a new C10 state from the CPU on desktop SKUs that enables a
+    lower power target that will be required by the California Energy
+    Commission (CEC). When FALSE, PS_ON is to be disabled.}
+    <b>0: Disable</b>; 1: Enable.
+  **/
+  UINT32                  PsOnEnable                   :  1;
+  /**
+    Enable/Disable platform support for CPU_C10_GATE# pin to control gating
+    of CPU VccIO and VccSTG rails instead of SLP_S0# pin. This policy needs
+    to be set if board design includes support for CPU_C10_GATE# pin.
+    0: Disable; <b>1: Enable</b>
+  **/
+  UINT32                  CpuC10GatePinEnable          :  1;
+  /**
+    Control whether to enable PMC debug messages to Trace Hub.
+    When Enabled, PMC HW will send debug messages to trace hub;
+    When Disabled, PMC HW will never send debug meesages to trace hub.
+    @note: When enabled, system may not enter S0ix
+    <b>0: Disable</b>; 1: Enable.
+  **/
+  UINT32                  PmcDbgMsgEn                  :  1;
+  /**
+    Enable/Disable ModPHY SUS Power Domain Dynamic Gating.
+    EXT_PWR_GATE# signal (if supported on platform) can be used to
+    control external FET for power gating ModPHY
+    @note: This setting is not supported and ignored on PCH-H
+    0: Disable; <b>1: Enable</b>.
+  **/
+  UINT32                  ModPhySusPgEnable            :  1;
+  /**
+    <b>(Test)</b>
+    This policy option enables USB2 PHY SUS Well Power Gating functionality.
+    @note: This setting is not supported and ignored on PCH-H
+    0: disable USB2 PHY SUS Well Power Gating
+    <b>1: enable USB2 PHY SUS Well Power Gating</b>
+  **/
+  UINT32                  Usb2PhySusPgEnable           :  1;
+  /**
+    Enable Os Idle Mode.
+    0: Disable; <b>1: Enable</b>.
+  **/
+  UINT32                  OsIdleEnable                 :  1;
+  /**
+    Enable control using EXT_PWR_GATE# pin of external FET
+    to power gate v1p05-PHY
+    <b>0: Disable</b>; 1: Enable.
+  **/
+  UINT32                  V1p05PhyExtFetControlEn      :  1;
+  /**
+    Enable control using EXT_PWR_GATE2# pin of external FET
+    to power gate v1p05-IS supply
+    <b>0: Disable</b>; 1: Enable.
+  **/
+  UINT32                  V1p05IsExtFetControlEn       :  1;
+  /**
+    Enable/Disable the Low Power Mode Host S0ix Auto-Demotion
+    feature. This feature enables the PMC to autonomously manage
+    the deepest allowed S0ix substate to combat thrashing between
+    power management states.
+    0: Disable; <b>1: Enable</b>.
+  **/
+  UINT32                  S0ixAutoDemotion             :  1;
+  /**
+    Enable/Disable Latch Events C10 Exit. When this bit is set to 1,
+    SLP_S0# entry events in SLP_S0_DEBUG_REGx registers are captured
+    on C10 exit (instead of C10 entry which is default)
+    <b>0: Disable</b>; 1: Enable.
+  **/
+  UINT32                  LatchEventsC10Exit           :  1;
+  UINT32                  RsvdBits1                    :  10;
+  /*
+    Power button debounce configuration
+    Debounce time can be specified in microseconds. Only certain values according
+    to below formula are supported:
+     DebounceTime = (2 ^ PADCFG_DW2.DEBOUNCE)*(glitch filter clock period).
+    RTC clock with f = 32 KHz is used for glitch filter.
+     DebounceTime = (2 ^ PADCFG_DW2.DEBOUNCE)*(31.25 us).
+    Supported DebounceTime values are following:
+     DebounceTime = 0 -> Debounce feature disabled
+     DebounceTime > 0 && < 250us -> Not supported
+     DebounceTime = 250us - 1024000us -> Supported range (DebounceTime = 250us * 2^n)
+    For values not supported by HW, they will be rounded down to closest supported one
+    <b>Default is 0</b>
+  */
+  UINT32                  PowerButtonDebounce;
+  /**
+    Reset Power Cycle Duration could be customized in the unit of second. Please refer to EDS
+    for all support settings. PCH HW default is 4 seconds, and range is 1~4 seconds, where
+    <b>0 is default</b>, 1 is 1 second, 2 is 2 seconds, ... 4 is 4 seconds.
+    And make sure the setting correct, which never less than the following register.
+    - GEN_PMCON_B.SLP_S3_MIN_ASST_WDTH
+    - GEN_PMCON_B.SLP_S4_MIN_ASST_WDTH
+    - PWRM_CFG.SLP_A_MIN_ASST_WDTH
+    - PWRM_CFG.SLP_LAN_MIN_ASST_WDTH
+  **/
+  UINT8                   PchPwrCycDur;
+  /**
+    Specifies the Pcie Pll Spread Spectrum Percentage
+    The value of this policy is in 1/10th percent units.
+    Valid spread range is 0-20. A value of 0xFF is reserved for AUTO.
+    A value of 0 is SSC of 0.0%. A value of 20 is SSC of 2.0%
+    The default is <b>0xFF: AUTO - No BIOS override</b>.
+  **/
+  UINT8                   PciePllSsc;
+  /**
+    Tells BIOS to enable C10 dynamic threshold adjustment mode.
+    BIOS will only attemt to enable it on PCH SKUs which support it.
+  **/
+  UINT8                   C10DynamicThresholdAdjustment;
+  UINT8                   Rsvd0[1];                             ///< Reserved bytes
+  /**
+    <b>(Test)</b>
+    Low Power Mode Enable/Disable config.
+    Configure if respective S0i2/3 sub-states are to be supported
+    by the platform. By default all sub-states are enabled but
+    for test purpose respective states can be disabled.
+    <b>Default is 0xFF</b>
+  **/
+  PMC_LPM_S0IX_SUB_STATE_EN      LpmS0ixSubStateEnable;
+  /*
+    Set true to enable Timed GPIO 0 timer.
+    <b>0: Disable</b>, 1: Enable
+  */
+  UINT32                  EnableTimedGpio0             : 1;
+  /*
+    Set true to enable Timed GPIO 1 timer.
+    <b>0: Disable</b>, 1: Enable
+  */
+  UINT32                  EnableTimedGpio1             : 1;
+  UINT32                  Rsvdbits                     : 30;
+
+  /**
+    Set true to enable override of Global Reset Event/Trigger masks.
+    Values from GlobalResetTriggerMask and GlobalResetEventMask will
+    be used as override value.
+    <b>0: Disable</b>, 1: Enable
+  **/
+  UINT8                   GlobalResetMasksOverride;
+  UINT8                   Rsvd1[3];             ///< Reserved bytes
+  /*
+    Mask for enabling Global Reset Trigger prevention
+  */
+  PMC_GLOBAL_RESET_MASK   GlobalResetTriggerMask;
+  /*
+    Mask for enabling Global Reset Event prevention
+  */
+  PMC_GLOBAL_RESET_MASK   GlobalResetEventMask;
+} PCH_PM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _PM_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Psf/PsfConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Psf/PsfConfig.h
new file mode 100644
index 0000000000..033e416b83
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Psf/PsfConfig.h
@@ -0,0 +1,32 @@
+/** @file
+  Primary Sideband Fabric policy.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PSF_CONFIG_H_
+#define _PSF_CONFIG_H_
+
+#define PSF_CONFIG_REVISION 1
+extern EFI_GUID gPsfConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  The PSF_CONFIG block describes the expected configuration of the Primary
+  Sideband Fabric.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER  Header;           ///< Config Block Header
+  /**
+    Psf Tcc (Time Coordinated Computing) Enable will decrease psf transaction latency by disable
+    some psf power management features. <b>0: Disable</b>; 1: Enable.
+  **/
+  UINT32    TccEnable                :  1;
+  UINT32    RsvdBits0                : 31;       ///< Reserved bits
+} PSF_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _PSF_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Rst/RstConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Rst/RstConfig.h
new file mode 100644
index 0000000000..469d46a205
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Rst/RstConfig.h
@@ -0,0 +1,82 @@
+/** @file
+  Rst policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _RST_CONFIG_H_
+#define _RST_CONFIG_H_
+#include <PchLimits.h>
+#include <ConfigBlock.h>
+
+#define RST_CONFIG_REVISION 1
+extern EFI_GUID gRstConfigGuid;
+
+#pragma pack (push,1)
+
+typedef enum {
+  SataOromDelay2sec,
+  SataOromDelay4sec,
+  SataOromDelay6sec,
+  SataOromDelay8sec
+} SATA_OROM_DELAY;
+
+/**
+  This structure describes the details of Intel RST for PCIe Storage remapping
+  Note: In order to use this feature, Intel RST Driver is required
+**/
+typedef struct {
+  /**
+    This member describes whether or not the Intel RST for PCIe Storage remapping should be enabled. <b>0: Disable</b>; 1: Enable.
+    Note 1: If Sata Controller is disabled, PCIe Storage Remapping should be disabled as well
+    Note 2: If PCIe Storage remapping is enabled, the PCH integrated AHCI controllers Class Code is configured as RAID
+  **/
+  UINT32   Enable                 :  1;
+  /**
+    Intel RST for PCIe Storage remapping - PCIe Port Selection (1-based, <b>0 = autodetect</b>)
+    The supported ports for PCIe Storage remapping is different depend on the platform and cycle router
+  **/
+  UINT32   RstPcieStoragePort     :  5;
+  /**
+    PCIe Storage Device Reset Delay in milliseconds (ms), which it guarantees such delay gap is fulfilled
+    before PCIe Storage Device configuration space is accessed after an reset caused by the link disable and enable step.
+    Default value is <b>100ms</b>.
+  **/
+  UINT32   DeviceResetDelay       :  8;
+  UINT32   RsvdBits0              : 18; ///< Reserved bits
+
+} RST_HARDWARE_REMAPPED_STORAGE_CONFIG;
+
+/**
+  Rapid Storage Technology settings.
+
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                             ///< Config Block Header
+
+  UINT32  Raid0              :  1;         ///< 0  : Disable; <b>1  : Enable</b> RAID0
+  UINT32  Raid1              :  1;         ///< 0  : Disable; <b>1  : Enable</b> RAID1
+  UINT32  Raid10             :  1;         ///< 0  : Disable; <b>1  : Enable</b> RAID10
+  UINT32  Raid5              :  1;         ///< 0  : Disable; <b>1  : Enable</b> RAID5
+  UINT32  Irrt               :  1;         ///< 0  : Disable; <b>1  : Enable</b> Intel Rapid Recovery Technology
+  UINT32  OromUiBanner       :  1;         ///< 0  : Disable; <b>1  : Enable</b> OROM UI and BANNER
+  UINT32  OromUiDelay        :  2;         ///< <b>00b  : 2 secs</b>; 01b  : 4 secs; 10b  : 6 secs; 11  : 8 secs (see  : SATA_OROM_DELAY)
+  UINT32  HddUnlock          :  1;         ///< 0  : Disable; <b>1  : Enable</b>. Indicates that the HDD password unlock in the OS is enabled
+  UINT32  LedLocate          :  1;         ///< 0  : Disable; <b>1  : Enable</b>. Indicates that the LED/SGPIO hardware is attached and ping to locate feature is enabled on the OS
+  UINT32  IrrtOnly           :  1;         ///< 0  : Disable; <b>1  : Enable</b>. Allow only IRRT drives to span internal and external ports
+  UINT32  SmartStorage       :  1;         ///< 0  : Disable; <b>1  : Enable</b> RST Smart Storage caching Bit
+  UINT32  LegacyOrom         :  1;         ///< <b>0  : Disable</b>; 1  : Enable RST Legacy OROM
+  UINT32  OptaneMemory       :  1;         ///< 0: Disable; <b>1: Enable</b> RST Optane(TM) Memory
+  UINT32  CpuAttachedStorage :  1;         ///< 0: Disable; <b>1: Enable</b> CPU Attached Storage
+  UINT32  RsvdBits0          : 17;         ///< Reserved Bits
+  /**
+    This member describes the details of implementation of Intel RST for PCIe Storage remapping (Intel RST Driver is required)
+    Note: RST for PCIe Sorage remapping is supported only for first SATA controller if more controllers are available
+  **/
+  RST_HARDWARE_REMAPPED_STORAGE_CONFIG   HardwareRemappedStorageConfig[PCH_MAX_RST_PCIE_STORAGE_CR];
+} RST_CONFIG;
+
+#pragma pack (pop)
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Rtc/RtcConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Rtc/RtcConfig.h
new file mode 100644
index 0000000000..1f354c10ae
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Rtc/RtcConfig.h
@@ -0,0 +1,38 @@
+/** @file
+  RTC policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _RTC_CONFIG_H_
+#define _RTC_CONFIG_H_
+
+#define RTC_CONFIG_REVISION 1
+extern EFI_GUID gRtcConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  The RTC_CONFIG block describes the expected configuration of RTC configuration.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header
+  /**
+    When set, prevents RTC TS (BUC.TS) from being changed.
+    This BILD bit has different function compared to LPC/eSPI, SPI.
+    0: Disabled; <b>1: Enabled</b>
+  **/
+  UINT32  BiosInterfaceLock       :  1;
+  /**
+    When set, bytes 38h-3Fh in the upper 128bytes bank of RTC RAM are locked
+    and cannot be accessed.
+    Writes will be droipped and reads will not return any guaranteed data.
+    0: Disabled; <b>1: Enabled</b>
+  **/
+  UINT32  MemoryLock              :  1;
+  UINT32  RsvdBits0               : 30;
+} RTC_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _RTC_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Sata/SataConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Sata/SataConfig.h
new file mode 100644
index 0000000000..c560fdd3ab
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Sata/SataConfig.h
@@ -0,0 +1,168 @@
+/** @file
+  Sata policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SATA_CONFIG_H_
+#define _SATA_CONFIG_H_
+
+#include <PchLimits.h>
+
+#define SATA_CONFIG_REVISION 1
+extern EFI_GUID gSataConfigGuid;
+
+#pragma pack (push,1)
+
+typedef enum  {
+  SataModeAhci,
+  SataModeRaid,
+  SataModeMax
+} SATA_MODE;
+
+typedef enum {
+  SataSpeedDefault,
+  SataSpeedGen1,
+  SataSpeedGen2,
+  SataSpeedGen3
+} SATA_SPEED;
+
+typedef enum {
+  SataRstMsix,
+  SataRstMsi,
+  SataRstLegacy
+} SATA_RST_INTERRUPT;
+
+typedef enum {
+  SataRaidClient,
+  SataRaidAlternate,
+  SataRaidServer
+} SATA_RAID_DEV_ID;
+
+/**
+  This structure configures the features, property, and capability for each SATA port.
+**/
+typedef struct {
+  /**
+    Enable SATA port.
+    It is highly recommended to disable unused ports for power savings
+  **/
+  UINT32  Enable           :  1;                  ///< 0: Disable; <b>1: Enable</b>
+  UINT32  HotPlug          :  1;                  ///< <b>0: Disable</b>; 1: Enable
+  UINT32  InterlockSw      :  1;                  ///< <b>0: Disable</b>; 1: Enable
+  UINT32  External         :  1;                  ///< <b>0: Disable</b>; 1: Enable
+  UINT32  SpinUp           :  1;                  ///< <b>0: Disable</b>; 1: Enable the COMRESET initialization Sequence to the device
+  UINT32  SolidStateDrive  :  1;                  ///< <b>0: HDD</b>; 1: SSD
+  UINT32  DevSlp           :  1;                  ///< <b>0: Disable</b>; 1: Enable DEVSLP on the port
+  UINT32  EnableDitoConfig :  1;                  ///< <b>0: Disable</b>; 1: Enable DEVSLP Idle Timeout settings (DmVal, DitoVal)
+  UINT32  DmVal            :  4;                  ///< DITO multiplier. Default is <b>15</b>.
+  UINT32  DitoVal          : 10;                  ///< DEVSLP Idle Timeout (DITO), Default is <b>625</b>.
+  /**
+    Support zero power ODD <b>0: Disable</b>, 1: Enable.
+    This is also used to disable ModPHY dynamic power gate.
+  **/
+  UINT32  ZpOdd             :  1;
+  UINT32  DevSlpResetConfig :  4;                 ///< 0: Hardware default; <b>0x01: GpioResumeReset</b>; 0x03: GpioHostDeepReset; 0x05: GpioPlatformReset; 0x07: GpioDswReset
+  UINT32  SataPmPtm         :  1;                 ///< Deprecated
+  UINT32  RxPolarity        :  1;                 ///< <b>0: Disable</b>; 1: Enable; Rx Polarity
+  UINT32  RsvdBits0         :  3;                 ///< Reserved fields for future expansion w/o protocol change
+} PCH_SATA_PORT_CONFIG;
+
+/**
+  This structure lists PCH supported SATA thermal throttling register setting for customization.
+  The settings is programmed through SATA Index/Data registers.
+  When the SuggestedSetting is enabled, the customized values are ignored.
+**/
+typedef struct {
+  UINT32  P0T1M                   :  2; ///< Port 0 T1 Multipler
+  UINT32  P0T2M                   :  2; ///< Port 0 T2 Multipler
+  UINT32  P0T3M                   :  2; ///< Port 0 T3 Multipler
+  UINT32  P0TDisp                 :  2; ///< Port 0 Tdispatch
+
+  UINT32  P1T1M                   :  2; ///< Port 1 T1 Multipler
+  UINT32  P1T2M                   :  2; ///< Port 1 T2 Multipler
+  UINT32  P1T3M                   :  2; ///< Port 1 T3 Multipler
+  UINT32  P1TDisp                 :  2; ///< Port 1 Tdispatch
+
+  UINT32  P0Tinact                :  2; ///< Port 0 Tinactive
+  UINT32  P0TDispFinit            :  1; ///< Port 0 Alternate Fast Init Tdispatch
+  UINT32  P1Tinact                :  2; ///< Port 1 Tinactive
+  UINT32  P1TDispFinit            :  1; ///< Port 1 Alternate Fast Init Tdispatch
+  UINT32  SuggestedSetting        :  1; ///< 0: Disable; <b>1: Enable</b> suggested representative values
+  UINT32  RsvdBits0               :  9; ///< Reserved bits
+} SATA_THERMAL_THROTTLING;
+
+/**
+   The SATA_CONFIG block describes the expected configuration of the SATA controllers.
+
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                             ///< Config Block Header
+  ///
+  /// This member describes whether or not the SATA controllers should be enabled. 0: Disable; <b>1: Enable</b>.
+  ///
+  UINT8                         Enable;
+  UINT8                         TestMode;       ///< <b>(Test)</b> <b>0: Disable</b>; 1: Allow entrance to the PCH SATA test modes
+  UINT8                         SalpSupport;    ///< 0: Disable; <b>1: Enable</b> Aggressive Link Power Management
+  UINT8                         PwrOptEnable;   ///< 0: Disable; <b>1: Enable</b> SATA Power Optimizer on PCH side.
+  /**
+    EsataSpeedLimit
+    When enabled, BIOS will configure the PxSCTL.SPD to 2 to limit the eSATA port speed.
+    Please be noted, this setting could be cleared by HBA reset, which might be issued
+    by EFI AHCI driver when POST time, or by SATA inbox driver/RST driver after POST.
+    To support the Speed Limitation when POST, the EFI AHCI driver should preserve the
+    setting before and after initialization. For support it after POST, it's dependent on
+    driver's behavior.
+    <b>0: Disable</b>; 1: Enable
+  **/
+  UINT8                         EsataSpeedLimit;
+  UINT8                         LedEnable;       ///< SATA LED indicates SATA controller activity. 0: Disable; <b>1: Enable</b> SATA LED.
+  /**
+    This option allows to configure SATA controller device ID while in RAID mode.
+    Refer to SATA_RAID_DEV_ID enumeration for supported options.
+    Choosing Client will allow RST driver loading, RSTe driver will not be able to load
+    Choosing Alternate will not allow RST inbox driver loading in Windows
+    Choosing Server will allow RSTe driver loading, RST driver will not load
+    <b>0: Client</b>; 1: Alternate; 2: Server
+  **/
+  UINT8                        RaidDeviceId;
+  /**
+    Controlls which interrupts will be linked to SATA controller CAP list
+    This option will take effect only if SATA controller is in RAID mode
+    Default: <b>PchSataMsix</b>
+  **/
+  UINT8                         SataRstInterrupt;
+
+  /**
+    Determines the system will be configured to which SATA mode.
+    Refer to SATA_MODE enumeration for supported options. Default is <b>SataModeAhci</b>.
+  **/
+  UINT8                         SataMode;
+  /**
+    Indicates the maximum speed the SATA controller can support.
+    Refer to SATA_SPEED enumeration for supported options.
+    <b>0h: SataSpeedDefault</b>; 1h: 1.5 Gb/s (Gen 1); 2h: 3 Gb/s(Gen 2); 3h: 6 Gb/s (Gen 1)
+  **/
+  UINT8                         SpeedLimit;
+  UINT8                         EnclosureSupport;   ///< Enclosure Management Support. 0: Disable; 1: Enable
+  /**
+    Controlls whenever Serial GPIO support is enabled for controller
+    <b>0: Disable</b>; 1: Enable
+  **/
+  UINT8                         SgpioSupport;
+  /**
+    This member configures the features, property, and capability for each SATA port.
+  **/
+  PCH_SATA_PORT_CONFIG          PortSettings[PCH_MAX_SATA_PORTS];
+  /**
+    This field decides the settings of Sata thermal throttling. When the Suggested Setting
+    is enabled, PCH RC will use the suggested representative values.
+  **/
+  SATA_THERMAL_THROTTLING       ThermalThrottling;
+} SATA_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _SATA_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Scs/ScsConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Scs/ScsConfig.h
new file mode 100644
index 0000000000..2ebc901896
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Scs/ScsConfig.h
@@ -0,0 +1,139 @@
+/** @file
+  Scs policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SCS_CONFIG_H_
+#define _SCS_CONFIG_H_
+
+#include <ConfigBlock.h>
+#include <PchLimits.h>
+
+#define SCS_SDCARD_CONFIG_REVISION     1
+#define SCS_EMMC_CONFIG_REVISION       1
+#define SCS_EMMC_DXE_CONFIG_REVISION   1
+#define SCS_SDCARD_MAX_DATA_GPIOS      4
+#define SCS_EMMC_MAX_DATA_GPIOS        8
+extern EFI_GUID gSdCardConfigGuid;
+extern EFI_GUID gEmmcConfigGuid;
+extern EFI_GUID gUfsConfigGuid;
+extern EFI_GUID gEmmcDxeConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  This structre holds the DLL configuration
+  register values that will be programmed by RC
+  if EnableCustomDlls field is set to TRUE. Those
+  policies should be used by platform if default values
+  provided by RC are not sufficient to provide stable operation
+  at all supported spped modes. RC will blindly set the DLL values
+  as provided in this structre.
+
+  For help with obtaining valid DLL values for your platform please
+  contact enabling support.
+**/
+typedef struct {
+  UINT32  TxCmdDelayControl;      // Offset 820h: Tx CMD Delay Control
+  UINT32  TxDataDelayControl1;    // Offset 824h: Tx Data Delay Control 1
+  UINT32  TxDataDelayControl2;    // Offset 828h: Tx Data Delay Control 2
+  UINT32  RxCmdDataDelayControl1; // Offset 82Ch: Rx CMD + Data Delay Control 1
+  UINT32  RxCmdDataDelayControl2; // Offset 834h: Rx CMD + Data Delay Control 2
+  UINT32  RxStrobeDelayControl;   // Offset 830h: Rx Strobe Delay Control, valid only for eMMC
+} SCS_SD_DLL;
+
+/**
+  SD GPIO settings
+**/
+typedef struct {
+  /**
+    GPIO signals pin muxing settings. If signal can be enable only on a single pin
+    then this parameter should be set to 0. Refer to GPIO_*_MUXING_SDCARD_*x_* in GpioPins*.h
+    for supported settings on a given platform
+  **/
+  UINT32   PinMux;
+  /**
+    GPIO Pads Internal Termination.
+    For more information please see Platform Design Guide.
+    Check GPIO_ELECTRICAL_CONFIG for reference
+  **/
+  UINT32   PadTermination;
+} MUX_GPIO_PARAM;
+
+typedef struct {
+  MUX_GPIO_PARAM PowerEnable;
+  MUX_GPIO_PARAM Cmd;
+  MUX_GPIO_PARAM Data[SCS_SDCARD_MAX_DATA_GPIOS];
+  MUX_GPIO_PARAM Cdb;
+  MUX_GPIO_PARAM Clk;
+  MUX_GPIO_PARAM Wp;
+} SCS_SDCARD_GPIO_CONFIG;
+
+typedef struct {
+  MUX_GPIO_PARAM Cmd;
+  MUX_GPIO_PARAM Data[SCS_EMMC_MAX_DATA_GPIOS];
+  MUX_GPIO_PARAM Rclk;
+  MUX_GPIO_PARAM Clk;
+  MUX_GPIO_PARAM Resetb;
+} SCS_EMMC_GPIO_CONFIG;
+
+typedef struct {
+  CONFIG_BLOCK_HEADER  Header;
+
+  UINT32      Enable                : 1;  ///<  Enable/Disable SdCard 0: Disabled, <b>1: Enabled</b>
+  UINT32      PowerEnableActiveHigh : 1;  ///<  Determine SD_PWREN# polarity 0: Active low, <b>1: Active high</b>
+  UINT32      UseCustomDlls         : 1;  ///<  Use tuned DLL values from policy <b>0: Use default DLL</b>, 1: Use values from TunedDllValues field
+  UINT32      Reserved              : 29;
+  SCS_SD_DLL  CustomDllValues;            ///<  Structure containing custom DLL values for SD card
+  SCS_SDCARD_GPIO_CONFIG GpioConfig;
+} SCS_SDCARD_CONFIG;
+
+typedef struct {
+  UINT32  Hs400RxValue : 7;  ///< Value of the tuned HS400 Rx value
+  UINT32  Hs400TxValue : 7;  ///< Value of the tuned HS400 Tx value
+  UINT32  Reserved     : 18;
+} SCS_EMMC_TUNED_DLL;
+
+typedef struct {
+  CONFIG_BLOCK_HEADER  Header;
+
+  UINT32      Enable         : 1;  ///<  Enable/Disable eMMC 0: Disabled, <b>1: Enabled</b>
+  UINT32      Hs400Supported : 1;  ///<  Enable/Disable eMMC HS400 support 0: Disabled, <b>1: Enabled</b>
+  UINT32      UseCustomDlls  : 1;  ///<  Use custom DLL values from policy <b>0: Use default DLL</b>, 1: Use values from TunedDllValues field
+  UINT32      Reserved       : 29;
+  SCS_SD_DLL  CustomDllValues;     ///<  Structure containing custom DLL values for eMMC                    ///< Structure containing tuned DLL settings for eMMC
+  SCS_EMMC_GPIO_CONFIG GpioConfig;
+} SCS_EMMC_CONFIG;
+
+typedef enum {
+  DriverStrength33Ohm = 0,
+  DriverStrength40Ohm,
+  DriverStrength50Ohm
+} SCS_EMMC_DRIVER_STRENGTH;
+
+typedef struct {
+  UINT32  TuningSuccessful  : 1;  ///< Informs software tuning module about previous software tuning status.
+  UINT32  Hs400RxValue      : 7;  ///< Value of the tuned HS400 Rx value returned from software tuning module
+  UINT32  Hs400TxValue      : 7;  ///< Value of the tuned HS400 Tx value returned from software tuning module
+  UINT32  Reserved          : 17;
+} SCS_EMMC_SOFTWARE_TUNING_RESULTS;
+
+typedef struct {
+  CONFIG_BLOCK_HEADER  Header;
+
+  UINT32   EnableSoftwareHs400Tuning         : 1;           ///< Enable/Disable software eMMC HS400 tuning: <b>0 - Disable</b>, 1 - Enable
+  UINT32   DriverStrength                    : 2;           ///< I/O driver strength: 0 - 33 Ohm, <b>1 - 40 Ohm</b>, 2 - 50 Ohm
+  UINT32   Reserved                          : 29;
+  EFI_LBA  TuningLba;                                       ///< Specifies LBA which will be used during software tuning process.
+  SCS_EMMC_SOFTWARE_TUNING_RESULTS  PreviousTuningResults;  ///< Informes software tuning module about previous software tuning results.} SCS_EMMC_DXE_CONFIG;
+} SCS_EMMC_DXE_CONFIG;
+
+typedef struct {
+  UINT32  Enable   : 1;  ///< Enable/Disable UFS controller 0: Disabled, <b>1: Enabled</b>
+  UINT32  Reserved : 31;
+} SCS_UFS_CONTROLLER_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _SCS_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/SerialIo/SerialIoConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/SerialIo/SerialIoConfig.h
new file mode 100644
index 0000000000..d76937cf59
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/SerialIo/SerialIoConfig.h
@@ -0,0 +1,32 @@
+/** @file
+  Serial IO policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SERIAL_IO_CONFIG_H_
+#define _SERIAL_IO_CONFIG_H_
+
+#define SERIAL_IO_CONFIG_REVISION 1
+extern EFI_GUID gSerialIoConfigGuid;
+
+#include <SerialIoDevices.h>
+
+#pragma pack (push,1)
+
+/**
+  The SERIAL_IO_CONFIG block provides the configurations to set the Serial IO controllers
+
+  <b>Revision 1:</b>
+  - Inital version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                                              ///< Config Block Header
+  SERIAL_IO_SPI_CONFIG  SpiDeviceConfig[PCH_MAX_SERIALIO_SPI_CONTROLLERS];   ///< SPI Configuration
+  SERIAL_IO_I2C_CONFIG  I2cDeviceConfig[PCH_MAX_SERIALIO_I2C_CONTROLLERS];   ///< I2C Configuration
+  SERIAL_IO_UART_CONFIG UartDeviceConfig[PCH_MAX_SERIALIO_UART_CONTROLLERS]; ///< UART Configuration
+} SERIAL_IO_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _SERIAL_IO_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/SiConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/SiConfig.h
new file mode 100644
index 0000000000..7ee4554b1d
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/SiConfig.h
@@ -0,0 +1,152 @@
+/** @file
+  Si Config Block
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SI_CONFIG_H_
+#define _SI_CONFIG_H_
+
+#define SI_CONFIG_REVISION  2
+
+extern EFI_GUID gSiConfigGuid;
+
+
+#pragma pack (push,1)
+
+/**
+  The Silicon Policy allows the platform code to publish a set of configuration
+  information that the RC drivers will use to configure the silicon hardware.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Added TraceHubMemBase
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;  ///< Offset 0 - 27 Config Block Header
+  //
+  // Platform specific common policies that used by several silicon components.
+  //
+  UINT8  CsmFlag;                ///< CSM status flag.
+  /**
+    This is used to skip the SSID programming in silicon code.
+    When set to TRUE, silicon code will not do any SSID programming and platform code
+    needs to handle that by itself properly.
+    <b>0: FALSE</b>, 1: TRUE
+  **/
+  UINT8  SkipSsidProgramming;
+  UINT8  RsvdBytes0[2];
+  /**
+    When SkipSsidProgramming is FALSE, silicon code will use this as default value
+    to program the SVID for all internal devices.
+    <b>0: use silicon default SVID 0x8086 </b>, Non-zero: use customized SVID.
+  **/
+  UINT16 CustomizedSvid;
+  /**
+    When SkipSsidProgramming is FALSE, silicon code will use this as default value
+    to program the Sid for all internal devices.
+    <b>0: use silicon default SSID 0x7270 </b>, Non-zero: use customized SSID.
+  **/
+  UINT16 CustomizedSsid;
+  /**
+    SsidTablePtr contains the SVID_SID_INIT_ENTRY table.
+    This is valid when SkipSsidProgramming is FALSE;
+    It doesn't need to contain entries for all Intel internal devices.
+    It can only contains the SVID_SID_INIT_ENTRY entries for those Dev# Func# which needs
+    to be overridden.
+    In the enties, only Dev, Function, SubSystemVendorId, and SubSystemId are required.
+    <b>Default is NULL.</b>
+
+    E.g. Platform only needs to override BDF 0:31:5 to AAAA:BBBB and BDF 0:31:3 to CCCC:DDDD,
+    it can be done in platform like this:
+    STATIC SVID_SID_INIT_ENTRY mSsidTablePtr[SI_MAX_DEVICE_COUNT] = {0};
+
+    VOID SiPolicyUpdate () {
+      UINT32 EntryCount = 0;
+      SiPolicy->SkipSsidProgramming = FALSE;
+      SiPolicy->SsidTablePtr = mSsidTablePtr;
+
+      mSsidTablePtr[EntryCount].Address.Bits.Device   = SpiDeviceNumber ();
+      mSsidTablePtr[EntryCount].Address.Bits.Function = SpiFunctionNumber ();
+      mSsidTablePtr[EntryCount].SvidSidValue.SubSystemVendorId = 0xAAAA;
+      mSsidTablePtr[EntryCount].SvidSidValue.SubSystemId       = 0xBBBB;
+      EntryCount ++;
+      mSsidTablePtr[EntryCount].Address.Bits.Device   = HdaDevNumber ();
+      mSsidTablePtr[EntryCount].Address.Bits.Function = HdaFuncNumber ();
+      mSsidTablePtr[EntryCount].SvidSidValue.SubSystemVendorId = 0xCCCC;
+      mSsidTablePtr[EntryCount].SvidSidValue.SubSystemId       = 0xDDDD;
+      EntryCount ++;
+      ASSERT (EntryCount < SI_MAX_DEVICE_COUNT);
+      SiPolicy->NumberOfSsidTableEntry = EntryCount;
+    }
+  **/
+  UINT32 *SsidTablePtr;
+  /**
+    Number of valid enties in SsidTablePtr.
+    This is valid when SkipSsidProgramming is FALSE;
+    <b>Default is 0.</b>
+  **/
+  UINT16 NumberOfSsidTableEntry;
+  UINT8  RsvdBytes1[2];
+  /**
+    If Trace Hub is enabled and trace to memory is desired, Platform code or BootLoader needs to allocate trace hub memory
+    as reserved, and save allocated memory base to TraceHubMemBase to ensure Trace Hub memory is configured properly.
+    To get total trace hub memory size please refer to TraceHubCalculateTotalBufferSize ()
+
+    Noted: If EDKII memory service is used to allocate memory, it will require double memory size to support size-aligned memory allocation,
+    so Platform code or FSP Wrapper code should ensure enough memory available for size-aligned TraceHub memory allocation.
+  **/
+  UINT32 TraceHubMemBase;        // Offset 58
+  /**
+    This is used to skip setting BIOS_DONE MSR during firmware update boot mode.
+    When set to TRUE and boot mode is BOOT_ON_FLASH_UPDATE,
+    skip setting BIOS_DONE MSR at EndofPei.
+    <b>0: FALSE</b>, 1: TRUE
+  **/
+  UINT8  SkipBiosDoneWhenFwUpdate;
+  UINT8  RsvdBytes2[3];
+} SI_CONFIG;
+
+#pragma pack (pop)
+
+#define DEFAULT_SSVID        0x8086
+#define DEFAULT_SSDID        0x7270
+#define SI_MAX_DEVICE_COUNT  70
+
+///
+/// Subsystem Vendor ID / Subsystem ID
+///
+typedef struct {
+  UINT16         SubSystemVendorId;
+  UINT16         SubSystemId;
+} SVID_SID_VALUE;
+
+//
+// Below is to match PCI_SEGMENT_LIB_ADDRESS () which can directly send to PciSegmentRead/Write functions.
+//
+typedef struct {
+  union {
+    struct {
+      UINT32  Register:12;
+      UINT32  Function:3;
+      UINT32  Device:5;
+      UINT32  Bus:8;
+      UINT32  Reserved1:4;
+      UINT32  Segment:16;
+      UINT32  Reserved2:16;
+    } Bits;
+    UINT64    SegBusDevFuncRegister;
+  } Address;
+  SVID_SID_VALUE SvidSidValue;
+  UINT32 Reserved;
+} SVID_SID_INIT_ENTRY;
+
+
+typedef struct {
+  UINT32  SkipBus;
+  UINT32  SkipDevice;
+  UINT32  SkipFunction;
+} SVID_SID_SKIP_TABLE;
+
+#endif // _SI_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/SiPreMemConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/SiPreMemConfig.h
new file mode 100644
index 0000000000..4bf014e9ba
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/SiPreMemConfig.h
@@ -0,0 +1,67 @@
+/** @file
+  Si Config Block PreMem
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SI_PREMEM_CONFIG_H_
+#define _SI_PREMEM_CONFIG_H_
+
+#define SI_PREMEM_CONFIG_REVISION  1
+
+extern EFI_GUID gSiPreMemConfigGuid;
+
+typedef enum {
+  ProbeTypeDisabled    = 0x00,
+  ProbeTypeDciOob      = 0x02,
+  ProbeTypeUsb3Dbc     = 0x03,
+  ProbeTypeXdp3        = 0x04,
+  ProbeTypeUsb2Dbc     = 0x05,
+  ProbeType2WireDciOob = 0x06,
+  ProbeTypeManual      = 0x07,
+  ProbeTypeMax
+} PLATFORM_DEBUG_CONSENT_PROBE_TYPE;
+
+#pragma pack (push,1)
+/**
+  The Silicon PreMem Policy allows the platform code to publish a set of configuration
+  information that the RC drivers will use to configure the silicon hardware.
+
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;  ///< Offset 0 - 27 Config Block Header
+  /**
+    Platform Debug Consent
+    As a master switch to enable platform debug capability and relevant settings with specified probe type.
+    Manual: Do not use Platform Debug Consent to override other debug-relevant policies, but the user must set each debug option manually, aimed at advanced users.
+
+    PDC-dependent policies are listed:
+    DciPreMemConfig->DciEn
+    DciPreMemConfig->DciDbcMode
+    CpuTraceHubConfig->EnableMode
+    CpuTraceHubConfig->CpuTraceHubMemReg0Size
+    CpuTraceHubConfig->CpuTraceHubMemReg1Size
+    PchTraceHubPreMemConfig->EnableMode
+    PchTraceHubPreMemConfig->MemReg0Size
+    PchTraceHubPreMemConfig->MemReg1Size
+
+    Note: DCI OOB (aka BSSB) uses CCA probe.
+    Refer to definition of PLATFORM_DEBUG_CONSENT_PROBE_TYPE
+    <b>0:Disabled</b>; 2:DCI OOB; 3:USB3 DbC; 4:XDP3/MIPI60 5:USB2 DbC; 6:2-wire DCI OOB; 7:Manual
+  **/
+  UINT32    PlatformDebugConsent  :  4;
+  UINT32    RsvdBits              : 28;
+  /**
+    This is used to skip override boot mode during firmware update boot mode.
+    When set to TRUE and boot mode is BOOT_ON_FLASH_UPDATE,
+    skip setting boot mode to BOOT_WITH_FULL_CONFIGURATION in PEI memory init.
+    <b>0: FALSE</b>, 1: TRUE
+  **/
+  UINT8     SkipOverrideBootModeWhenFwUpdate;
+  UINT8     RsvdBytes[3];
+} SI_PREMEM_CONFIG;
+
+#pragma pack (pop)
+#endif // _SI_PREMEM_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Smbus/SmbusConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Smbus/SmbusConfig.h
new file mode 100644
index 0000000000..36f96a4f32
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Smbus/SmbusConfig.h
@@ -0,0 +1,50 @@
+/** @file
+  Smbus policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SMBUS_CONFIG_H_
+#define _SMBUS_CONFIG_H_
+
+#define SMBUS_PREMEM_CONFIG_REVISION 1
+extern EFI_GUID gSmbusPreMemConfigGuid;
+
+#pragma pack (push,1)
+
+#define PCH_MAX_SMBUS_RESERVED_ADDRESS 128
+
+///
+/// The SMBUS_CONFIG block lists the reserved addresses for non-ARP capable devices in the platform.
+///
+typedef struct {
+  /**
+    Revision 1: Init version
+  **/
+  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header
+  /**
+    This member describes whether or not the SMBus controller of PCH should be enabled.
+    0: Disable; <b>1: Enable</b>.
+  **/
+  UINT32  Enable             :  1;
+  UINT32  ArpEnable          :  1;      ///< Enable SMBus ARP support, <b>0: Disable</b>; 1: Enable.
+  UINT32  DynamicPowerGating :  1;      ///< <b>(Test)</b> <b>Disable</b> or Enable Smbus dynamic power gating.
+  ///
+  /// <b>(Test)</b> SPD Write Disable, 0: leave SPD Write Disable bit; <b>1: set SPD Write Disable bit.</b>
+  /// For security recommendations, SPD write disable bit must be set.
+  ///
+  UINT32  SpdWriteDisable    :  1;
+  UINT32  SmbAlertEnable     :  1;      ///< Enable SMBus Alert pin (SMBALERT#). 0: <b>Disabled<b>, 1: Enabled.
+  UINT32  RsvdBits0          : 27;      ///< Reserved bits
+  UINT16  SmbusIoBase;                  ///< SMBUS Base Address (IO space). Default is <b>0xEFA0</b>.
+  UINT8   Rsvd0;                        ///< Reserved bytes
+  UINT8   NumRsvdSmbusAddresses;        ///< The number of elements in the RsvdSmbusAddressTable.
+  /**
+    Array of addresses reserved for non-ARP-capable SMBus devices.
+  **/
+  UINT8   RsvdSmbusAddressTable[PCH_MAX_SMBUS_RESERVED_ADDRESS];
+} PCH_SMBUS_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _SMBUS_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Spi/SpiConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Spi/SpiConfig.h
new file mode 100644
index 0000000000..f3e52ff453
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Spi/SpiConfig.h
@@ -0,0 +1,43 @@
+/** @file
+  PCH SPI Flash Controller config block
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SPI_CONFIG_H_
+#define _SPI_CONFIG_H_
+
+#define SPI_CONFIG_REVISION 1
+extern EFI_GUID gSpiConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  Basic configuration for option features of PCH SPI Flash controller
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER  Header;           ///< Config Block Header
+  /**
+    Enable extended BIOS Direct Read Region feature
+    Enabling this will make all memory accesses in a decode range to be translated
+    to BIOS region reads from SPI flash
+    <b>0: Disabled</b>, 1: Enabled
+  **/
+  UINT32    ExtendedBiosDecodeRangeEnable   :  1;
+  UINT32    RsvdBits0                       : 31;       ///< Reserved bits
+  /**
+    Base address that will be used for Extended Decode Range.
+    This will be ignored when ExtendedBiosDecodeRangeEnable is set to 0.
+  **/
+  UINT32    ExtendedBiosDecodeRangeBase;
+  /**
+    Limit address that will be used for Extended Decode Range.
+    This will be ignored when ExtendedBiosDecodeRangeEnable is set to 0.
+  **/
+  UINT32    ExtendedBiosDecodeRangeLimit;
+} SPI_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _SPI_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Tcss/TcssPeiConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Tcss/TcssPeiConfig.h
new file mode 100644
index 0000000000..53af4ccd45
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Tcss/TcssPeiConfig.h
@@ -0,0 +1,145 @@
+/** @file
+  TCSS PEI policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _TCSS_PEI_CONFIG_H_
+#define _TCSS_PEI_CONFIG_H_
+
+#include <ConfigBlock.h>
+#include <UsbConfig.h>
+#include <TcssInfo.h>
+
+#define TCSS_PEI_CONFIG_REVISION 2
+extern EFI_GUID gTcssPeiConfigGuid;
+
+#pragma pack (push,1)
+
+
+#define MAX_IOM_AUX_BIAS_COUNT 4
+
+///
+/// The IOM_AUX_ORI_PAD_CONFIG describes IOM TypeC port map GPIO pin.
+/// Those GPIO setting for DP Aux Orientation Bias Control when the TypeC port didn't have re-timer.
+/// IOM needs know Pull-Up and Pull-Down pin for Bias control
+///
+typedef struct {
+  UINT32     GpioPullN; ///< GPIO Pull Up Ping number that is for IOM indecate the pull up pin from TypeC port.
+  UINT32     GpioPullP; ///< GPIO Pull Down Ping number that is for IOM indecate the pull down pin from TypeC port.
+} IOM_AUX_ORI_PAD_CONFIG;
+
+///
+/// The IOM_EC_INTERFACE_CONFIG block describes interaction between BIOS and IOM-EC.
+///
+
+typedef struct {
+  UINT32     VccSt;         ///< IOM VCCST request. (Not equal to actual VCCST value)
+  UINT32     UsbOverride;   ///< IOM to override USB connection.
+  UINT32     D3ColdEnable;  ///< Enable/disable D3 Cold support in TCSS
+  UINT32     D3HotEnable;   ///< Enable/disable D3 Hot support in TCSS
+} IOM_INTERFACE_CONFIG;
+
+///
+/// The PMC_INTERFACE_CONFIG block describes interaction between BIOS and PMC
+///
+typedef struct {
+  UINT8      PmcPdEnable;    ///< PMC PD Solution Enable
+  UINT8      Rsvd[3];
+} PMC_INTERFACE_CONFIG;
+
+///
+/// The SA XDCI INT Pin and IRQ number
+///
+typedef struct {
+  UINT8      IntPing;  ///< Int Pin Number
+  UINT8      Irq;      ///< Irq Number
+  UINT16     Rsvd;
+} SA_XDCI_IRQ_INT_CONFIG;
+
+///
+/// The TCSS_PCIE_PORT_POLICY block describes PCIe settings for TCSS.
+///
+typedef struct {
+  UINT8   AcsEnabled;                         ///< Indicate whether the ACS is enabled. 0: Disable; <b>1: Enable</b>.
+  UINT8   DpcEnabled;                         ///< Downstream Port Containment. 0: Disable; <b>1: Enable</b>
+  UINT8   RpDpcExtensionsEnabled;             ///< RP Extensions for Downstream Port Containment. 0: Disable; <b>1: Enable</b>
+  UINT8   LtrEnable;                          ///< Latency Tolerance Reporting Mechanism. <b>0: Disable</b>; 1: Enable.
+  UINT8   PtmEnabled;                         ///< Enables PTM capability
+
+  UINT8   Aspm;                               ///< The ASPM configuration of the root port (see: PCH_PCIE_ASPM_CONTROL). Default is <b>
+  UINT8   SlotNumber;                         ///< Indicates the slot number for the root port. Default is the value as root port index.
+  UINT8   SlotPowerLimitScale;                ///< <b>(Test)</b> Specifies scale used for slot power limit value. Leave as 0 to set to default. Default is <b>zero</b>.
+  UINT16  SlotPowerLimitValue;                ///< <b>(Test)</b> Specifies upper limit on power supplies by slot. Leave as 0 to set to default. Default is <b>zero</b>.
+
+  UINT8   AdvancedErrorReporting;             ///< Indicate whether the Advanced Error Reporting is enabled. <b>0: Disable</b>; 1: Enable.
+  UINT8   UnsupportedRequestReport;           ///< Indicate whether the Unsupported Request Report is enabled. <b>0: Disable</b>; 1: Enable.
+  UINT8   FatalErrorReport;                   ///< Indicate whether the Fatal Error Report is enabled. <b>0: Disable</b>; 1: Enable.
+  UINT8   NoFatalErrorReport;                 ///< Indicate whether the No Fatal Error Report is enabled. <b>0: Disable</b>; 1: Enable.
+  UINT8   CorrectableErrorReport;             ///< Indicate whether the Correctable Error Report is enabled. <b>0: Disable</b>; 1: Enable.
+  UINT8   SystemErrorOnFatalError;            ///< Indicate whether the System Error on Fatal Error is enabled. <b>0: Disable</b>; 1: Enable.
+  UINT8   SystemErrorOnNonFatalError;         ///< Indicate whether the System Error on Non Fatal Error is enabled. <b>0: Disable</b>; 1: Enable.
+  UINT8   SystemErrorOnCorrectableError;      ///< Indicate whether the System Error on Correctable Error is enabled. <b>0: Disable</b>; 1: Enable.
+
+  UINT16  LtrMaxSnoopLatency;                 ///< Latency Tolerance Reporting, Max Snoop Latency.
+  UINT16  LtrMaxNoSnoopLatency;               ///< Latency Tolerance Reporting, Max Non-Snoop Latency.
+  UINT8   SnoopLatencyOverrideMode;           ///< Latency Tolerance Reporting, Snoop Latency Override Mode.
+  UINT8   SnoopLatencyOverrideMultiplier;     ///< Latency Tolerance Reporting, Snoop Latency Override Multiplier.
+  UINT16  SnoopLatencyOverrideValue;          ///< Latency Tolerance Reporting, Snoop Latency Override Value.
+  UINT8   NonSnoopLatencyOverrideMode;        ///< Latency Tolerance Reporting, Non-Snoop Latency Override Mode.
+  UINT8   NonSnoopLatencyOverrideMultiplier;  ///< Latency Tolerance Reporting, Non-Snoop Latency Override Multiplier.
+  UINT16  NonSnoopLatencyOverrideValue;       ///< Latency Tolerance Reporting, Non-Snoop Latency Override Value.
+  UINT8   ForceLtrOverride;                   ///< <b>0: Disable</b>; 1: Enable.
+  UINT8   LtrConfigLock;                      ///< <b>0: Disable</b>; 1: Enable.
+} TCSS_PCIE_PORT_POLICY;
+
+///
+/// TCSS_PCIE_PEI_POLICY describes PCIe port settings for TCSS.
+///
+typedef struct {
+  TCSS_PCIE_PORT_POLICY  PciePortPolicy[MAX_ITBT_PCIE_PORT];
+} TCSS_PCIE_PEI_POLICY;
+
+///
+/// The TCSS_IOM_PEI_CONFIG block describes IOM Aux/HSL override settings for TCSS.
+///
+typedef struct {
+  UINT16    AuxOri;     ///< Bits defining value for IOM Aux Orientation Register
+  UINT16    HslOri;     ///< Bits defining value for IOM HSL Orientation Register
+} TCSS_IOM_ORI_OVERRIDE;
+
+///
+/// The TCSS_IOM_PEI_CONFIG block describes IOM settings for TCSS.
+///
+typedef struct {
+  IOM_AUX_ORI_PAD_CONFIG    IomAuxPortPad[MAX_IOM_AUX_BIAS_COUNT]; ///< The IOM_AUX_ORI_BIAS_CTRL port config setting.
+  TCSS_IOM_ORI_OVERRIDE     IomOverrides;
+  IOM_INTERFACE_CONFIG      IomInterface;                          ///< Config settings are BIOS <-> IOM interface.
+  PMC_INTERFACE_CONFIG      PmcInterface;                          ///< Config settings for BIOS <-> PMC interface
+  UINT8                     TcStateLimit;                          ///< Tcss C-State deep stage
+  UINT8                     Usb3ComplModeEnable;
+  UINT8                     Reserved[2];                           ///< Reserved bytes for future use
+} TCSS_IOM_PEI_CONFIG;
+
+///
+/// The TCSS_MISC_PEI_CONFIG block describes MISC settings for TCSS.
+///
+typedef struct {
+  SA_XDCI_IRQ_INT_CONFIG    SaXdci;   ///< System Agent Xdci Int Pin and Irq setting
+  UINT32                    Rsvd;     ///< Reserved bytes for future use, align to multiple 4
+} TCSS_MISC_PEI_CONFIG;
+
+///
+/// The TCSS_PEI_CONFIG block describes TCSS settings for SA.
+///
+typedef struct {
+  CONFIG_BLOCK_HEADER     Header;     ///< Offset 0-27 Config Block Header
+  TCSS_PCIE_PEI_POLICY    PciePolicy; ///< The PCIe Config
+  USB_CONFIG              UsbConfig;  ///< USB config is shared between PCH and SA.
+  TCSS_IOM_PEI_CONFIG     IomConfig;  ///< The Iom Config
+  TCSS_MISC_PEI_CONFIG    MiscConfig; ///< The MISC Config
+} TCSS_PEI_CONFIG;
+
+#pragma pack (pop)
+
+#endif /* _TCSS_PEI_CONFIG_H_ */
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Thc/ThcConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Thc/ThcConfig.h
new file mode 100644
index 0000000000..23c3750216
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Thc/ThcConfig.h
@@ -0,0 +1,73 @@
+/** @file
+  Touch Host Controller policy.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _THC_CONFIG_H_
+#define _THC_CONFIG_H_
+
+#define THC_CONFIG_REVISION 1
+extern EFI_GUID gThcConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  Available Port Assignments
+
+**/
+typedef enum {
+  ThcAssignmentNone, ///< None of the avaialbe controllers assigned
+  ThcAssignmentThc0, ///< Port assigned to THC0
+  ThcAssignmentThc1  ///< Port assigned to THC1
+} THC_PORT_ASSIGNMENT;
+
+
+/**
+  Port Configuration structure required for each Port that THC might use.
+
+**/
+typedef struct {
+  UINT32 Assignment;         ///< Sets THCx assignment see THC_PORT_ASSIGNMENT
+  UINT32 InterruptPinMuxing; ///< Each GPIO PORTx/SPIx INTB Pin has different muxing options refer to GPIO_*_MUXING_THC_SPIx_*
+} THC_PORT;
+
+/**
+  THC_CONFIG block provides the configurations forTouch Host Controllers
+
+  Assignment field in each THC port controlls the THC behavior.
+
+  Available scenarios:
+  1: Single Port 0 used by THC0
+      - THC0 Enabled
+      - Port0 assigned to THC0
+      - Port1 unassigned
+      - THC1 will be automatically Disabled.
+  2: Both ports used by THC0
+      - THC0 Enabled
+      - Port0 assigned to THC0
+      - Port1 assigned to THC0
+      - THC1 will be automatically Disabled.
+  3: Port 0 used by THC0 and Port 1 used by THC1
+      - THC0 Enabled
+      - Port0 assigned to THC0
+      - THC1 Enabled
+      - Port1 assigned to THC1.
+<b>4: Both Ports unassigned.</b>
+      Both THC Controllers will be disabled in that case.
+
+  @note
+  Invalid scenario that will cause ASSERT.
+  1. Same port Number assigned to THC0 or THC1.
+  2. Two Ports assigned to THC1.
+
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER  Header;           ///< Config Block Header
+  THC_PORT             ThcPort[2];       ///< Port Configuration
+} THC_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _THC_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Thermal/ThermalConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Thermal/ThermalConfig.h
new file mode 100644
index 0000000000..a952f74238
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Thermal/ThermalConfig.h
@@ -0,0 +1,153 @@
+/** @file
+  Thermal policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _THERMAL_CONFIG_H_
+#define _THERMAL_CONFIG_H_
+
+#define THERMAL_CONFIG_REVISION 1
+extern EFI_GUID gThermalConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  This structure lists PCH supported throttling register setting for custimization.
+  When the SuggestedSetting is enabled, the customized values are ignored.
+**/
+typedef struct {
+  UINT32 T0Level                  :  9; ///< Custimized T0Level value. If SuggestedSetting is used, this setting is ignored.
+  UINT32 T1Level                  :  9; ///< Custimized T1Level value. If SuggestedSetting is used, this setting is ignored.
+  UINT32 T2Level                  :  9; ///< Custimized T2Level value. If SuggestedSetting is used, this setting is ignored.
+  UINT32 TTEnable                 :  1; ///< Enable the thermal throttle function. If SuggestedSetting is used, this settings is ignored.
+  /**
+    When set to 1 and the programmed GPIO pin is a 1, then PMSync state 13 will force at least T2 state.
+    If SuggestedSetting is used, this setting is ignored.
+  **/
+  UINT32 TTState13Enable          :  1;
+  /**
+    When set to 1, this entire register (TL) is locked and remains locked until the next platform reset.
+    If SuggestedSetting is used, this setting is ignored.
+  **/
+  UINT32 TTLock                   :  1;
+  UINT32 SuggestedSetting         :  1; ///< 0: Disable; <b>1: Enable</b> suggested representative values.
+  /**
+    ULT processors support thermal management and cross thermal throttling between the processor package
+    and LP PCH. The PMSYNC message from PCH to CPU includes specific bit fields to update the PCH
+    thermal status to the processor which is factored into the processor throttling.
+    Enable/Disable PCH Cross Throttling; 0: Disabled, 1: <b>Enabled</b>.
+  **/
+  UINT32 PchCrossThrottling       :  1;
+  UINT32 Rsvd0;                      ///< Reserved bytes
+} THERMAL_THROTTLE_LEVELS;
+
+//
+// Supported Thermal Sensor Target Width
+//
+typedef enum {
+  DmiThermSensWidthX1  = 0,
+  DmiThermSensWidthX2  = 1,
+  DmiThermSensWidthX4  = 2,
+  DmiThermSensWidthX8  = 3,
+  DmiThermSensWidthX16 = 4
+} DMI_THERMAL_SENSOR_TARGET_WIDTH;
+
+/**
+  This structure allows to customize DMI HW Autonomous Width Control for Thermal and Mechanical spec design.
+  When the SuggestedSetting is enabled, the customized values are ignored.
+  Look at DMI_THERMAL_SENSOR_TARGET_WIDTH for possible values
+**/
+typedef struct {
+  UINT32  DmiTsawEn               :  1; ///< DMI Thermal Sensor Autonomous Width Enable
+  UINT32  SuggestedSetting        :  1; ///< 0: Disable; <b>1: Enable</b> suggested representative values
+  UINT32  RsvdBits0               :  6; ///< Reserved bits
+  UINT32  TS0TW                   :  3; ///< Thermal Sensor 0 Target Width (<b>DmiThermSensWidthx8</b>)
+  UINT32  TS1TW                   :  3; ///< Thermal Sensor 1 Target Width (<b>DmiThermSensWidthx4</b>)
+  UINT32  TS2TW                   :  3; ///< Thermal Sensor 2 Target Width (<b>DmiThermSensWidthx2</b>)
+  UINT32  TS3TW                   :  3; ///< Thermal Sensor 3 Target Width (<b>DmiThermSensWidthx1</b>)
+  UINT32  RsvdBits1               : 12; ///< Reserved bits
+} DMI_HW_WIDTH_CONTROL;
+
+/**
+  This structure configures PCH memory throttling thermal sensor GPIO PIN settings
+**/
+typedef struct {
+  /**
+    GPIO PM_SYNC enable, 0:Diabled, 1:<b>Enabled</b>
+    When enabled, RC will overrides the selected GPIO native mode.
+    For GPIO_C, PinSelection 0: CPU_GP_0 (default) or 1: CPU_GP_1
+    For GPIO_D, PinSelection 0: CPU_GP_3 (default) or 1: CPU_GP_2
+    For CNL: CPU_GP_0 is GPP_E3, CPU_GP_1 is GPP_E7, CPU_GP_2 is GPP_B3, CPU_GP_3 is GPP_B4.
+  **/
+  UINT32  PmsyncEnable     :  1;
+  UINT32  C0TransmitEnable :  1;        ///< GPIO Transmit enable in C0 state, 0:Disabled, 1:<b>Enabled</b>
+  UINT32  PinSelection     :  1;        ///< GPIO Pin assignment selection, <b>0: default</b>, 1: secondary
+  UINT32  RsvdBits0        : 29;
+} TS_GPIO_PIN_SETTING;
+
+enum PCH_PMSYNC_GPIO_X_SELECTION {
+  TsGpioC,
+  TsGpioD,
+  MaxTsGpioPin
+};
+
+/**
+  This structure supports an external memory thermal sensor (TS-on-DIMM or TS-on-Board).
+**/
+typedef struct {
+  /**
+   This will enable PCH memory throttling.
+   While this policy is enabled, must also enable EnableExtts in SA policy.
+   <b>0: Disable</b>; 1: Enable
+  **/
+  UINT32   Enable           :  1;
+  UINT32   RsvdBits0        : 31;
+  /**
+    GPIO_C and GPIO_D selection for memory throttling.
+    It's strongly recommended to choose GPIO_C and GPIO_D for memory throttling feature,
+    and route EXTTS# accordingly.
+  **/
+  TS_GPIO_PIN_SETTING     TsGpioPinSetting[2];
+} PCH_MEMORY_THROTTLING;
+
+/**
+  The THERMAL_CONFIG block describes the expected configuration of the Thermal IP block.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header
+  UINT32  PchHotEnable            :  1; ///< Enable PCHHOT# pin assertion when temperature is higher than PchHotLevel. 0: <b>Disabled<b>, 1: Enabled.
+  UINT32  RsvdBits0               : 31;
+  /**
+    This field decides the settings of Thermal throttling. When the Suggested Setting
+    is enabled, PCH RC will use the suggested representative values.
+  **/
+  THERMAL_THROTTLE_LEVELS   TTLevels;
+  /**
+    This field decides the settings of DMI throttling. When the Suggested Setting
+    is enabled, PCH RC will use the suggested representative values.
+  **/
+  DMI_HW_WIDTH_CONTROL      DmiHaAWC;
+  /**
+    Memory Thermal Management settings
+  **/
+  PCH_MEMORY_THROTTLING     MemoryThrottling;
+  /**
+    The recommendation is the same as Cat Trip point.
+    This field decides the temperature, default is <b>120</b>.
+    Temperature value used for PCHHOT# pin assertion based on 2s complement format
+    - 0x001 positive 1'C
+    - 0x000 0'C
+    - 0x1FF negative 1'C
+    - 0x1D8 negative 40'C
+    - and so on
+  **/
+  UINT16                    PchHotLevel;
+  UINT8                     Rsvd0[6];
+
+
+} THERMAL_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _THERMAL_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/TraceHub/TraceHubConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/TraceHub/TraceHubConfig.h
new file mode 100644
index 0000000000..9c315fb4a4
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/TraceHub/TraceHubConfig.h
@@ -0,0 +1,101 @@
+/** @file
+  Configurations for CPU and PCH trace hub
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _TRACE_HUB_CONFIG_H_
+#define _TRACE_HUB_CONFIG_H_
+
+#include <ConfigBlock.h>
+
+#define CPU_TRACEHUB_PREMEM_CONFIG_REVISION 1
+#define PCH_TRACEHUB_PREMEM_CONFIG_REVISION 1
+
+extern EFI_GUID gPchTraceHubPreMemConfigGuid;
+extern EFI_GUID gCpuTraceHubPreMemConfigGuid;
+
+typedef enum {
+  CpuTraceHub,
+  PchTraceHub
+} TRACE_HUB_DEVICE;
+///
+/// The TRACE_HUB_ENABLE_MODE describes TraceHub mode of operation
+///
+typedef enum {
+  TraceHubModeDisabled       = 0,
+  TraceHubModeTargetDebugger = 1,
+  TraceHubModeHostDebugger   = 2,
+  TraceHubModeMax
+} TRACE_HUB_ENABLE_MODE;
+
+///
+/// The TRACE_BUFFER_SIZE describes the desired TraceHub buffer size
+///
+typedef enum {
+  TraceBufferNone,
+  TraceBuffer1M,
+  TraceBuffer8M,
+  TraceBuffer64M,
+  TraceBuffer128M,
+  TraceBuffer256M,
+  TraceBuffer512M,
+  TraceBufferMax
+} TRACE_BUFFER_SIZE;
+
+#pragma pack (push,1)
+///
+/// TRACE_HUB_CONFIG block describes TraceHub settings
+///
+typedef struct {
+  /**
+  Trace hub mode. Default is disabled.
+  Target Debugger mode refers to debug tool running on target device itself and it works as a conventional PCI device;
+  Host Debugger mode refers to SUT debugged via probe on host, configured as ACPI device with PCI configuration sapce hidden.
+  <b>0 = Disable</b>; 1 = Target Debugger mode; 2 = Host Debugger mode
+  Refer to TRACE_HUB_ENABLE_MODE
+  **/
+  UINT8                      EnableMode;
+  /**
+  Trace hub memory buffer region size policy.
+  The avaliable memory size options are: 0:0MB (none), 1:1MB, <b>2:8MB</b>, 3:64MB, 4:128MB, 5:256MB, 6:512MB.
+  Note : Limitation of total buffer size (CPU + PCH) is 512MB. If iTbt is enabled, the total size limits to 256 MB.
+  Refer to TRACE_BUFFER_SIZE
+  **/
+  UINT8                      MemReg0Size;
+  UINT8                      MemReg1Size;
+  /**
+  AET Trace. AET base address can be set to FW Base either from CPU trace hub or PCH one.
+  AetEnabled must be exclusive, if AetEnabled = 1 for CPU trace hub, must AetEnabled = 0 for PCH one.
+  The default is set to PCH.
+  CPU Trace Hub
+  <b>0 = Disabled</b>; 1 = Enabled
+  PCH Trace Hub
+  0 = Disabled; <b>1 = Enabled</b>
+  **/
+  UINT8                      AetEnabled;
+} TRACE_HUB_CONFIG;
+
+/**
+  CPU Trace Hub PreMem Configuration
+  Contains Trace Hub settings for CPU side tracing
+  <b>Revision 1</b>:  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER        Header;           ///< Config Block Header
+  TRACE_HUB_CONFIG           TraceHub;         ///< Trace Hub Config
+} CPU_TRACE_HUB_PREMEM_CONFIG;
+
+/**
+  PCH Trace Hub PreMem Configuration
+  Contains Trace Hub settings for PCH side tracing
+  <b>Revision 1</b>:  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER        Header;           ///< Config Block Header
+  TRACE_HUB_CONFIG           TraceHub;         ///< Trace Hub Config
+} PCH_TRACE_HUB_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Usb/Usb2PhyConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Usb/Usb2PhyConfig.h
new file mode 100644
index 0000000000..99063103c3
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Usb/Usb2PhyConfig.h
@@ -0,0 +1,81 @@
+/** @file
+  USB2 PHY configuration policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _USB2_PHY_CONFIG_H_
+#define _USB2_PHY_CONFIG_H_
+
+#include <UsbConfig.h>
+
+#define USB2_PHY_CONFIG_REVISION 1
+extern EFI_GUID gUsb2PhyConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  This structure configures per USB2 AFE settings.
+  It allows to setup the port electrical parameters.
+**/
+typedef struct {
+/** Per Port HS Preemphasis Bias (PERPORTPETXISET)
+  000b - 0mV
+  001b - 11.25mV
+  010b - 16.9mV
+  011b - 28.15mV
+  100b - 28.15mV
+  101b - 39.35mV
+  110b - 45mV
+  111b - 56.3mV
+**/
+  UINT8   Petxiset;
+/** Per Port HS Transmitter Bias (PERPORTTXISET)
+  000b - 0mV
+  001b - 11.25mV
+  010b - 16.9mV
+  011b - 28.15mV
+  100b - 28.15mV
+  101b - 39.35mV
+  110b - 45mV
+  111b - 56.3mV
+**/
+  UINT8   Txiset;
+/**
+  Per Port HS Transmitter Emphasis (IUSBTXEMPHASISEN)
+  00b - Emphasis OFF
+  01b - De-emphasis ON
+  10b - Pre-emphasis ON
+  11b - Pre-emphasis & De-emphasis ON
+**/
+  UINT8   Predeemp;
+/**
+  Per Port Half Bit Pre-emphasis (PERPORTTXPEHALF)
+  1b - half-bit pre-emphasis
+  0b - full-bit pre-emphasis
+**/
+  UINT8   Pehalfbit;
+} USB2_PHY_PARAMETERS;
+
+/**
+  This structure holds info on how to tune electrical parameters of USB2 ports based on board layout
+
+  <b>Revision 1</b>:
+  - Initial version.
+
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER     Header;                   ///< Config Block Header
+  /**
+    This structure configures per USB2 port physical settings.
+    It allows to setup the port location and port length, and configures the port strength accordingly.
+    Changing this policy values from default ones may require disabling USB2 PHY Sus Well Power Gating
+    through Usb2PhySusPgEnable on PCH-LP
+  **/
+  USB2_PHY_PARAMETERS          Port[MAX_USB2_PORTS];
+} USB2_PHY_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _USB2_PHY_CONFIG_H_
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Usb/Usb3HsioConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Usb/Usb3HsioConfig.h
new file mode 100644
index 0000000000..da816b1378
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Usb/Usb3HsioConfig.h
@@ -0,0 +1,138 @@
+/** @file
+  USB3 Mod PHY configuration policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _USB3_HSIO_CONFIG_H_
+#define _USB3_HSIO_CONFIG_H_
+
+#include <UsbConfig.h>
+
+#define USB3_HSIO_CONFIG_REVISION 2
+extern EFI_GUID gUsb3HsioConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  This structure describes USB3 Port N configuration parameters
+**/
+typedef struct {
+  /**
+    USB 3.0 TX Output Downscale Amplitude Adjustment (orate01margin)
+    HSIO_TX_DWORD8[21:16]
+    <b>Default = 00h</b>
+  **/
+  UINT8  HsioTxDownscaleAmp;
+  /**
+    USB 3.0 TX Output -3.5dB De-Emphasis Adjustment Setting (ow2tapgen2deemph3p5)
+    HSIO_TX_DWORD5[21:16]
+    <b>Default = 29h</b> (approximately -3.5dB De-Emphasis)
+  **/
+  UINT8  HsioTxDeEmph;
+  /**
+    Signed Magnatude number added to the CTLE code.(ctle_adapt_offset_cfg_4_0)
+    HSIO_RX_DWORD25 [20:16]
+    Ex: -1 -- 1_0001. +1: 0_0001
+    <b>Default = 0h</b>
+  **/
+  UINT8  HsioCtrlAdaptOffsetCfg;
+  /**
+    LFPS filter select for n (filter_sel_n_2_0)
+    HSIO_RX_DWORD51 [29:27]
+    0h:1.6ns
+    1h:2.4ns
+    2h:3.2ns
+    3h:4.0ns
+    4h:4.8ns
+    5h:5.6ns
+    6h:6.4ns
+    <b>Default = 0h</b>
+  **/
+  UINT8  HsioFilterSelN;
+  /**
+    LFPS filter select for p (filter_sel_p_2_0)
+    HSIO_RX_DWORD51 [26:24]
+    0h:1.6ns
+    1h:2.4ns
+    2h:3.2ns
+    3h:4.0ns
+    4h:4.8ns
+    5h:5.6ns
+    6h:6.4ns
+    <b>Default = 0h</b>
+  **/
+  UINT8  HsioFilterSelP;
+  /**
+    Controls the input offset (olfpscfgpullupdwnres_sus_usb_2_0)
+    HSIO_RX_DWORD51 [2:0]
+    000 Prohibited
+    001 45K
+    010 Prohibited
+    011 31K
+    100 36K
+    101 36K
+    110 36K
+    111 36K
+    <b>Default = 3h</b>
+  **/
+  UINT8  HsioOlfpsCfgPullUpDwnRes;
+
+  UINT8  HsioTxDeEmphEnable;             ///< Enable the write to USB 3.0 TX Output -3.5dB De-Emphasis Adjustment, <b>0: Disable</b>; 1: Enable.
+  UINT8  HsioTxDownscaleAmpEnable;       ///< Enable the write to USB 3.0 TX Output Downscale Amplitude Adjustment, <b>0: Disable</b>; 1: Enable.
+  UINT8  HsioCtrlAdaptOffsetCfgEnable;   ///< Enable the write to Signed Magnatude number added to the CTLE code, <b>0: Disable</b>; 1: Enable.
+  UINT8  HsioFilterSelNEnable;           ///< Enable the write to LFPS filter select for n, <b>0: Disable</b>; 1: Enable.
+  UINT8  HsioFilterSelPEnable;           ///< Enable the write to LFPS filter select for p, <b>0: Disable</b>; 1: Enable.
+  UINT8  HsioOlfpsCfgPullUpDwnResEnable; ///< Enable the write to olfpscfgpullupdwnres, <b>0: Disable</b>; 1: Enable.
+  /**
+    USB 3.0 TX Output - Unique Transition Bit Scale for rate 3 (rate3UniqTranScale)
+    HSIO_TX_DWORD9[6:0]
+    <b>Default = 4Ch</b>
+  **/
+  UINT8  HsioTxRate3UniqTran;
+  /**
+    USB 3.0 TX Output -Unique Transition Bit Scale for rate 2 (rate2UniqTranScale)
+    HSIO_TX_DWORD9[14:8]
+    <b>Default = 4Ch</b>
+  **/
+  UINT8  HsioTxRate2UniqTran;
+  /**
+    USB 3.0 TX Output - Unique Transition Bit Scale for rate 1 (rate1UniqTranScale)
+    HSIO_TX_DWORD9[22:16]
+    <b>Default = 4Ch</b>
+  **/
+  UINT8  HsioTxRate1UniqTran;
+  /**
+    USB 3.0 TX Output - Unique Transition Bit Scale for rate 0 (rate0UniqTranScale)
+    HSIO_TX_DWORD9[30:24]
+    <b>Default = 4Ch</b>
+  **/
+  UINT8  HsioTxRate0UniqTran;
+
+  UINT8  HsioTxRate3UniqTranEnable; ///< Enable the write to USB 3.0 TX Unique Transition Bit Mode for rate 3, <b>0: Disable</b>; 1: Enable.
+  UINT8  HsioTxRate2UniqTranEnable; ///< Enable the write to USB 3.0 TX Unique Transition Bit Mode for rate 2, <b>0: Disable</b>; 1: Enable.
+  UINT8  HsioTxRate1UniqTranEnable; ///< Enable the write to USB 3.0 TX Unique Transition Bit Mode for rate 1, <b>0: Disable</b>; 1: Enable.
+  UINT8  HsioTxRate0UniqTranEnable; ///< Enable the write to USB 3.0 TX Unique Transition Bit Mode for rate 0, <b>0: Disable</b>; 1: Enable.
+} HSIO_PARAMETERS;
+
+/**
+  Structure for holding USB3 tuning parameters
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - USB 3.0 TX Output Unique Transition Bit Scale policies added
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER     Header;                   ///< Config Block Header
+  /**
+    These members describe whether the USB3 Port N of PCH is enabled by platform modules.
+  **/
+  HSIO_PARAMETERS         Port[MAX_USB3_PORTS];
+} USB3_HSIO_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _USB3_HSIO_CONFIG_H_
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Usb/UsbConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Usb/UsbConfig.h
new file mode 100644
index 0000000000..a1c7f0bb04
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Usb/UsbConfig.h
@@ -0,0 +1,149 @@
+/** @file
+  Common USB policy shared between PCH and CPU
+  Contains general features settings for xHCI and xDCI
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _USB_CONFIG_H_
+#define _USB_CONFIG_H_
+
+#define USB_CONFIG_REVISION 2
+extern EFI_GUID gUsbConfigGuid;
+
+#define MAX_USB2_PORTS  16
+#define MAX_USB3_PORTS  10
+
+#pragma pack (push,1)
+
+typedef UINT8                   USB_OVERCURRENT_PIN;
+#define USB_OC_SKIP             0xFF
+#define USB_OC_MAX_PINS         16       ///< Total OC pins number (both physical and virtual)
+
+/**
+  This structure configures per USB2.0 port settings like enabling and overcurrent protection
+**/
+typedef struct {
+  /**
+    These members describe the specific over current pin number of USB 2.0 Port N.
+    It is SW's responsibility to ensure that a given port's bit map is set only for
+    one OC pin Description. USB2 and USB3 on the same combo Port must use the same OC pin.
+  **/
+  UINT32     OverCurrentPin          :  8;
+  UINT32     Enable                  :  1;     ///< 0: Disable; <b>1: Enable</b>.
+  UINT32     PortResetMessageEnable  :  1;     ///< 0: Disable USB2 Port Reset Message; 1: Enable USB2 Port Reset Message
+  UINT32     RsvdBits0               : 22;     ///< Reserved bits
+} USB2_PORT_CONFIG;
+
+/**
+  This structure configures per USB3.x port settings like enabling and overcurrent protection
+**/
+typedef struct {
+  /**
+    These members describe the specific over current pin number of USB 3.x Port N.
+    It is SW's responsibility to ensure that a given port's bit map is set only for
+    one OC pin Description. USB2 and USB3 on the same combo Port must use the same OC pin.
+  **/
+  UINT32  OverCurrentPin               :  8;
+  UINT32  Enable                       :  1; ///< 0: Disable; <b>1: Enable</b>.
+  UINT32  RsvdBits0                    : 23; ///< Reserved bits
+} USB3_PORT_CONFIG;
+
+/**
+  The XDCI_CONFIG block describes the configurations
+  of the xDCI Usb Device controller.
+**/
+typedef struct {
+  /**
+    This member describes whether or not the xDCI controller should be enabled.
+    0: Disable; <b>1: Enable</b>.
+  **/
+  UINT32  Enable              :  1;
+  UINT32  RsvdBits0           : 31;     ///< Reserved bits
+} XDCI_CONFIG;
+
+
+/**
+  This member describes the expected configuration of the USB controller,
+  Platform modules may need to refer Setup options, schematic, BIOS specification to update this field.
+  The Usb20OverCurrentPins and Usb30OverCurrentPins field must be updated by referring the schematic.
+
+  <b>Revision 1</b>: - Initial version.
+  <b>Revision 2</b>: - Add USB3LinkSpeed
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER     Header;                   ///< Config Block Header
+  /**
+    This policy option when set will make BIOS program Port Disable Override register during PEI phase.
+    When disabled BIOS will not program the PDO during PEI phase and leave PDO register unlocked for later programming.
+    If this is disabled, platform code MUST set it before booting into OS.
+    <b>1: Enable</b>
+    0: Disable
+  **/
+  UINT32                  PdoProgramming               :  1;
+  /**
+    This option allows for control whether USB should program the Overcurrent Pins mapping into xHCI.
+    Disabling this feature will disable overcurrent detection functionality.
+    Overcurrent Pin mapping data is contained in respective port structures (i.e. USB30_PORT_CONFIG) in OverCurrentPin field.
+    By default this Overcurrent functionality should be enabled and disabled only for OBS debug usage.
+    <b>1: Will program USB OC pin mapping in respective xHCI controller registers</b>
+    0: Will clear OC pin mapping allow for OBS usage of OC pins
+  **/
+  UINT32                  OverCurrentEnable            :  1;
+  /**
+    <b>(Test)</b>
+    If this policy option is enabled then BIOS will program OCCFDONE bit in xHCI meaning that OC mapping data will be
+    consumed by xHCI and OC mapping registers will be locked. OverCurrent mapping data is taken from respective port data
+    structure from OverCurrentPin field.
+    If EnableOverCurrent policy is enabled this also should be enabled, otherwise xHCI won't consume OC mapping data.
+    <b>1: Program OCCFDONE bit and make xHCI consume OverCurrent mapping data</b>
+    0: Do not program OCCFDONE bit making it possible to use OBS debug on OC pins.
+  **/
+  UINT32                  XhciOcLock                   :  1;
+  /**
+    Enabling this feature will allow for overriding LTR values for xHCI controller.
+    Values used for programming will be taken from this config block and BIOS will disregard recommended ones.
+    <b>0: disable - do not override recommended LTR values</b>
+    1: enable - override recommended LTR values
+  **/
+  UINT32                  LtrOverrideEnable            :  1;
+  /**
+    This setting enable LBPM GEN1 speed
+    0: GEN2;
+    1: GEN1;
+  **/
+  UINT32                  USB3LinkSpeed                : 1;
+  UINT32                  RsvdBits0                    : 27;     ///< Reserved bits
+  /**
+    High Idle Time Control override value
+    This setting is used only if LtrOverrideEnable is enabled
+  **/
+  UINT32                  LtrHighIdleTimeOverride;
+  /**
+    Medium Idle Time Control override value
+    This setting is used only if LtrOverrideEnable is enabled
+  **/
+  UINT32                  LtrMediumIdleTimeOverride;
+  /**
+    Low Idle Time Control override value
+    This setting is used only if LtrOverrideEnable is enabled
+  **/
+  UINT32                  LtrLowIdleTimeOverride;
+  /**
+    These members describe whether the USB2 Port N of PCH is enabled by platform modules.
+  **/
+  USB2_PORT_CONFIG        PortUsb20[MAX_USB2_PORTS];
+  /**
+    These members describe whether the USB3 Port N of PCH is enabled by platform modules.
+  **/
+  USB3_PORT_CONFIG        PortUsb30[MAX_USB3_PORTS];
+  /**
+    This member describes whether or not the xDCI controller should be enabled.
+  **/
+  XDCI_CONFIG             XdciConfig;
+
+} USB_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _USB_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/VoltageRegulator/CpuPowerMgmtVrConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/VoltageRegulator/CpuPowerMgmtVrConfig.h
new file mode 100644
index 0000000000..8b01ecd262
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/VoltageRegulator/CpuPowerMgmtVrConfig.h
@@ -0,0 +1,114 @@
+/** @file
+  CPU Power Management VR Config Block.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _CPU_POWER_MGMT_VR_CONFIG_H_
+#define _CPU_POWER_MGMT_VR_CONFIG_H_
+
+#define CPU_POWER_MGMT_VR_CONFIG_REVISION 7
+
+extern EFI_GUID gCpuPowerMgmtVrConfigGuid;
+
+#pragma pack (push,1)
+
+///
+/// Defines the maximum number of VR domains supported.
+/// @warning: Changing this define would cause DWORD alignment issues in policy structures.
+///
+#define MAX_NUM_VRS         5
+
+/**
+  CPU Power Management VR Configuration Structure.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Updated Acoustic Noise Mitigation.
+  <b>Revision 3</b>:
+  - Deprecate PsysOffset and added PsysOffset1 for Psys Offset Correction
+  <b>Revision 4</b>:
+  - Deprecate TdcTimeWindow and added TdcTimeWindow1 for TDC Time
+    Added Irms support.
+  <b>Revision 5</b>:
+  - Add RfiMitigation.
+  <b>Revision 6</b>:
+  - Added an option to Enable/Disable FIVR Spread Spectrum
+  <b>Revision 7</b>:
+  - Add Dynamic Periodicity Alteration (DPA) tuning feature
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  UINT32 AcousticNoiseMitigation        : 1;      ///< Enable or Disable Acoustic Noise Mitigation feature. <b>0: Disabled</b>; 1: Enabled
+  /**
+   VR specific mailbox commands.
+   <b>00b - no VR specific command sent.</b>
+   01b - A VR mailbox command specifically for the MPS IMPV8 VR will be sent.
+   10b - VR specific command sent for PS4 exit issue.
+   11b - Reserved.
+   **/
+  UINT32 SendVrMbxCmd                   : 2;
+  UINT32 EnableMinVoltageOverride       : 1;      ///< Enable or disable Minimum Voltage override for minimum voltage runtime and minimum voltage C8. <b>0: Disabled</b> 1: Enabled.
+  UINT32 RfiMitigation                  : 1;      ///< Enable or Disable RFI Mitigation. <b>0: Disable - DCM is the IO_N default</b>; 1: Enable - Enable IO_N DCM/CCM switching as RFI mitigation.
+  UINT32 RsvdBits                       : 27;     ///< Reserved for future use.
+  UINT8  PsysSlope;                               ///< PCODE MMIO Mailbox: Platform Psys slope correction. <b>0: Auto</b> Specified in 1/100 increment values. Range is 0-200. 125 = 1.25.
+  UINT8  PsysOffset;                              ///< PCODE MMIO Mailbox: Platform Psys offset correction. <b>0: Auto</b> Units 1/4, Range 0-255. Value of 100 = 100/4 = 25 offset. Deprecated
+  UINT8  FivrSpreadSpectrum;                      ///< Set the Spread Spectrum Range. <b>1.5%</b>, Range: 0.5%, 1%, 1.5%, 2%, 3%, 4%, 5%, 6%. Each Range is translated to internally encoded values. 0.5% = 0, 1% = 3, 1.5% = 8, 2% = 18, 3% = 28, 4% = 34, 5% = 39, 6% = 44.
+  UINT8  RsvdBytes0;
+  /**
+   PCODE MMIO Mailbox: Set the desired RFI frequency, in increments of 100KHz.
+   <b>0: Auto</b>
+   Range varies based on XTAL clock:
+    - 0-1918 (Up to 191.8HMz) for 24MHz clock.
+    - 0-1535 (Up to 153.5MHz) for 19MHz clock.
+  **/
+  UINT16 FivrRfiFrequency;
+  UINT8  RsvdBytes1[2];
+  /** @name VR Settings
+  The VR related settings are sorted in an array where each index maps to the VR domain as defined below:
+   - 0 = System Agent VR
+   - 1 = IA Core VR
+   - 2 = Ring Vr
+   - 3 = GT VR
+   - 4 = FIVR VR
+
+  The VR settings for a given domain must be populated in the appropriate index.
+  **/
+  ///@{
+  UINT16 TdcCurrentLimit[MAX_NUM_VRS];            ///< PCODE MMIO Mailbox: Thermal Design Current current limit. Specified in 1/8A units. Range is 0-4095. 1000 = 125A. <b>0: 0 Amps</b>
+  UINT16 AcLoadline[MAX_NUM_VRS];                 ///< PCODE MMIO Mailbox: AcLoadline in 1/100 mOhms (ie. 1250 = 12.50 mOhm); Range is 0-6249. <b>Intel Recommended Defaults vary by domain and SKU.</b>
+  UINT16 DcLoadline[MAX_NUM_VRS];                 ///< PCODE MMIO Mailbox: DcLoadline in 1/100 mOhms (ie. 1250 = 12.50 mOhm); Range is 0-6249.<b>Intel Recommended Defaults vary by domain and SKU.</b>
+  UINT16 Psi1Threshold[MAX_NUM_VRS];              ///< PCODE MMIO Mailbox: Power State 1 current cuttof in 1/4 Amp increments. Range is 0-128A.
+  UINT16 Psi2Threshold[MAX_NUM_VRS];              ///< PCODE MMIO Mailbox: Power State 2 current cuttof in 1/4 Amp increments. Range is 0-128A.
+  UINT16 Psi3Threshold[MAX_NUM_VRS];              ///< PCODE MMIO Mailbox: Power State 3 current cuttof in 1/4 Amp increments. Range is 0-128A.
+  INT16  ImonOffset[MAX_NUM_VRS];                 ///< PCODE MMIO Mailbox: Imon offset correction. Value is a 2's complement signed integer. Units 1/1000, Range 0-63999. For an offset = 12.580, use 12580. <b>0: Auto</b>
+  UINT16 IccMax[MAX_NUM_VRS];                     ///< PCODE MMIO Mailbox: VR Icc Max limit. 0-255A in 1/4 A units. 400 = 100A. <b>Default: 0 - Auto, no override</b>
+  UINT16 VrVoltageLimit[MAX_NUM_VRS];             ///< PCODE MMIO Mailbox: VR Voltage Limit. Range is 0-7999mV.
+  UINT16 ImonSlope[MAX_NUM_VRS];                  ///< PCODE MMIO Mailbox: Imon slope correction. Specified in 1/100 increment values. Range is 0-200. 125 = 1.25. <b>0: Auto</b>
+  UINT8  Psi3Enable[MAX_NUM_VRS];                 ///< PCODE MMIO Mailbox: Power State 3 enable/disable; 0: Disable; <b>1: Enable</b>.
+  UINT8  Psi4Enable[MAX_NUM_VRS];                 ///< PCODE MMIO Mailbox: Power State 4 enable/disable; 0: Disable; <b>1: Enable</b>.
+  UINT8  VrConfigEnable[MAX_NUM_VRS];             ///< Enable/Disable BIOS configuration of VR; 0: Disable; <b>1: Enable.</b>
+  UINT8  TdcEnable[MAX_NUM_VRS];                  ///< PCODE MMIO Mailbox: Thermal Design Current enable/disable; <b>0: Disable; </b>1: Enable
+  UINT8  TdcTimeWindow[MAX_NUM_VRS];              ///< @deprecated. PCODE MMIO Mailbox: Thermal Design Current time window. Defined in milli seconds. <b>1ms default</b>
+  UINT8  TdcLock[MAX_NUM_VRS];                    ///< PCODE MMIO Mailbox: Thermal Design Current Lock; <b>0: Disable</b>; 1: Enable.
+  UINT8  FastPkgCRampDisable[MAX_NUM_VRS];        ///< Disable Fast Slew Rate for Deep Package C States for VR IA,GT,SA,VLCC,FIVR domain based on Acoustic Noise Mitigation feature enabled. <b>0: False</b>; 1: True
+  UINT8  SlowSlewRate[MAX_NUM_VRS];               ///< Slew Rate configuration for Deep Package C States for VR VR IA,GT,SA,VLCC,FIVR domain based on Acoustic Noise Mitigation feature enabled. <b>0: Fast/2</b>; 1: Fast/4; 2: Fast/8; 3: Fast/16
+  ///@}
+  UINT16 MinVoltageRuntime;                       ///< PCODE MMIO Mailbox: Minimum voltage for runtime. Valid if EnableMinVoltageOverride = 1 .Range 0 to 1999mV. <b> 0: 0mV </b>
+  UINT16 MinVoltageC8;                            ///< PCODE MMIO Mailbox: Minimum voltage for C8. Valid if EnableMinVoltageOverride = 1. Range 0 to 1999mV. <b> 0: 0mV </b>
+  UINT16 PsysOffset1;                             ///< PCODE MMIO Mailbox: Platform Psys offset correction. <b>0: Auto</b> Units 1/1000, Range 0-63999. For an offset of 25.348, enter 25348.
+  UINT8  RsvdBytes2[2];
+  UINT32 TdcTimeWindow1[MAX_NUM_VRS];             ///< PCODE MMIO Mailbox: Thermal Design Current time window. Defined in milli seconds. <b>1ms default</b>
+  UINT8  Irms[MAX_NUM_VRS];                       ///< PCODE MMIO Mailbox: Current root mean square. <b>0: Disable</b>; 1: Enable.
+  UINT8  FivrSpectrumEnable;                      ///< Enable or Disable FIVR Spread Spectrum 0: Disable; <b> 1: Enable.</b>
+  UINT8  Rsvd1[2];
+  UINT8  PreWake;                                 ///< PCODE MMIO Mailbox: Acoustic Noise Mitigation Range. This can be programmed only if AcousticNoiseMitigation is enabled.<b>Default Value = 0 micro ticks</b> Defines the max pre-wake randomization time in micro ticks. Range is 0-255.
+  UINT8  RampUp;                                  ///< PCODE MMIO Mailbox: Acoustic Noise Mitigation Range. This can be programmed only if AcousticNoiseMitigation is enabled.<b>Default Value = 0 micro ticks</b> Defines the max ramp up randomization time in micro ticks. Range is 0-255.
+  UINT8  RampDown;                                ///< PCODE MMIO Mailbox: Acoustic Noise Mitigation Range. This can be programmed only if AcousticNoiseMitigation is enabled.<b>Default Value = 0 micro ticks</b> Defines the max ramp down randomization time in micro ticks. Range is 0-255.
+  UINT8  Rsvd2[1];
+} CPU_POWER_MGMT_VR_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_POWER_MGMT_VR_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Vtd/VtdConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Vtd/VtdConfig.h
new file mode 100644
index 0000000000..74ca983a5d
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Vtd/VtdConfig.h
@@ -0,0 +1,64 @@
+/** @file
+  VT-d policy definitions.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _VTD_CONFIG_H_
+#define _VTD_CONFIG_H_
+
+#include <Library/VtdInfoLib.h>
+#pragma pack(push, 1)
+
+#define VTD_CONFIG_REVISION 1
+#define VTD_DXE_CONFIG_REVISION 2
+
+/**
+  The data elements should be initialized by a Platform Module.
+  The data structure is for VT-d driver initialization\n
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER  Header;                      ///< Offset 0-27 Config Block Header
+  /**
+    Offset 28:
+    VT-D Support can be verified by reading CAP ID register as expalined in BIOS Spec.
+    This policy is for debug purpose only.
+    If VT-D is not supported, all other policies in this config block will be ignored.
+    <b>0 = To use Vt-d</b>;
+    1 = Avoids programming Vtd bars, Vtd overrides and DMAR table.
+  **/
+  UINT8        VtdDisable;
+  UINT8        X2ApicOptOut;        ///< Offset 29 :This field is used to enable the X2APIC_OPT_OUT bit in the DMAR table. 1=Enable/Set and <b>0=Disable/Clear</b>
+  UINT8        DmaControlGuarantee; ///< Offset 30 :This field is used to enable the DMA_CONTROL_GUARANTEE bit in the DMAR table. 1=Enable/Set and <b>0=Disable/Clear</b>
+  UINT8        VtdIgdEnable;        ///< Offset 31 :This field is used to enable the VtdIgdEnable Policy. 1=Enable/Set and <b>0=Disable/Clear</b>
+  UINT8        VtdIpuEnable;        ///< Offset 32 :This field is used to enable the VtdIpuEnable Policy. 1=Enable/Set and <b>0=Disable/Clear</b>
+  UINT8        VtdIopEnable;        ///< Offset 33 :This field is used to enable the VtdIopEnable Policy. 1=Enable/Set and <b>0=Disable/Clear</b>
+  UINT8        VtdItbtEnable;       ///< Offset 34 :This field is used to enable the VtdItbtEnable Policy. 1=Enable/Set and <b>0=Disable/Clear</b>
+  UINT8        PreBootDmaMask;      ///< Offset 35 :Convey PcdVTdPolicyPropertyMask value from EDK2 IntelSiliconPkg
+  /**
+    Offset 36:
+    This field is used to describe the base addresses for VT-d function:\n
+    VTD BAR for Gfx if IGfx is supported : <b>BaseAddress[0]=0xFED90000,\n
+    VTD BAR for IPU if IPU is supporrted : BaseAddress[1]=0xFED92000,\n
+    VTD BAR for other DMA Agents (except Igfx and IPU) : BaseAddress[2]=0xFED91000,\n
+    VTD BAR for iTBT if iTBT is supported : BaseAddress[3]=0xFED84000, BaseAddress[4]=0xFED85000, BaseAddress[5]=0xFED86000,BaseAddress[6]=0xFED87000</b>
+  **/
+  UINT32       BaseAddress[VTD_ENGINE_NUMBER];
+  UINT32       DmaBufferSize;      ///< Offset 64 :Protect Memory Region (PMR) DMA buffer size
+
+
+} VTD_CONFIG;
+
+/**
+  The data structure is for VT-d driver initialization in DXE\n
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                    ///< Offset 0-27 Config Block Header
+} VTD_DXE_CONFIG;
+#pragma pack(pop)
+
+#endif   //  _VTD_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Wdt/WatchDogConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Wdt/WatchDogConfig.h
new file mode 100644
index 0000000000..8766762580
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock/Wdt/WatchDogConfig.h
@@ -0,0 +1,31 @@
+/** @file
+  WatchDog policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _WATCH_DOG_CONFIG_H_
+#define _WATCH_DOG_CONFIG_H_
+
+#define WATCH_DOG_PREMEM_CONFIG_REVISION 1
+extern EFI_GUID gWatchDogPreMemConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  This policy clears status bits and disable watchdog, then lock the
+  WDT registers.
+  while WDT is designed to be disabled and locked by Policy,
+  bios should not enable WDT by WDT PPI. In such case, bios shows the
+  warning message but not disable and lock WDT register to make sure
+  WDT event trigger correctly.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header
+  UINT32    DisableAndLock    :  1;     ///< <b>(Test)</b> Set 1 to clear WDT status, then disable and lock WDT registers. <b>0: Disable</b>; 1: Enable.
+  UINT32    RsvdBits          : 31;
+} PCH_WDT_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _WATCH_DOG_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SiPkg.dec b/Silicon/Intel/TigerlakeSiliconPkg/SiPkg.dec
new file mode 100644
index 0000000000..0c0f2db104
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SiPkg.dec
@@ -0,0 +1,1207 @@
+## @file
+#  Component description file for the Silicon Reference Code.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+DEC_SPECIFICATION = 0x00010017
+PACKAGE_NAME = SiPkg
+PACKAGE_VERSION = 0.1
+PACKAGE_GUID = F245E276-44A0-46b3-AEB5-9898BBCF008D
+
+[Includes.Common.Private]
+
+#
+# TigerLake Fru
+#
+Fru/TglCpu/IncludePrivate
+Fru/TglPch/IncludePrivate
+
+##
+# IpBlock IncludePrivate
+#
+IpBlock/Psf/IncludePrivate
+IpBlock/Pmc/IncludePrivate
+IpBlock/Smbus/IncludePrivate
+IpBlock/Graphics/IncludePrivate
+IpBlock/CpuPcieRp/IncludePrivate
+IpBlock/Hda/IncludePrivate
+IpBlock/PchDmi/IncludePrivate
+IpBlock/P2sb/IncludePrivate
+IpBlock/Spi/IncludePrivate
+IpBlock/Gpio/IncludePrivate
+IpBlock/Cnvi/IncludePrivate
+IpBlock/Gbe/IncludePrivate
+IpBlock/PcieRp/IncludePrivate
+IpBlock/Vtd/IncludePrivate
+IpBlock/HostBridge/IncludePrivate
+IpBlock/SerialIo/IncludePrivate
+
+SystemAgent/IncludePrivate
+
+Pch/IncludePrivate
+
+[Includes]
+#
+# TigerLake
+#
+Fru/TglCpu/Include
+Fru/TglPch/Include
+
+# CPU PCIe
+IpBlock/CpuPcieRp/Include
+
+IpBlock/Gpio/Include
+
+
+##
+#
+# This section is for IP ConfigBlock versions control
+#
+# - Memory
+Include/ConfigBlock/Memory/Ver2
+#
+# - Graphics
+Include/ConfigBlock/Graphics/Gen12
+#
+# - CPU PCIe
+Include/ConfigBlock/CpuPcieRp/Gen4
+Include/ConfigBlock/CpuDmi
+
+# - Hybrid Graphics
+Include/ConfigBlock/HybridGraphics
+
+Include
+#
+# SystemAgent
+#
+SystemAgent/Include
+SystemAgent/AcpiTables
+SystemAgent/AcpiTables/SaSsdt
+Include/ConfigBlock/Vtd
+Include/ConfigBlock/PcieRp
+Include/ConfigBlock/Gna
+Include/ConfigBlock/CpuPcieRp/Gen4
+Include/ConfigBlock/CpuDmi
+Include/ConfigBlock/HybridGraphics
+Include/ConfigBlock/HostBridge
+#
+# Cpu
+#
+Cpu/Include
+Include/ConfigBlock/Overclocking
+Include/ConfigBlock/VoltageRegulator
+
+#
+# Pch
+#
+Pch/Include
+Include/ConfigBlock/Thermal
+Include/ConfigBlock/P2sb
+Include/ConfigBlock/Ish
+Include/ConfigBlock/Usb
+Include/ConfigBlock/Espi
+Include/ConfigBlock/Fivr
+Include/ConfigBlock/Rtc
+Include/ConfigBlock/Smbus
+Include/ConfigBlock/Pmc
+Include/ConfigBlock/Itss
+Include/ConfigBlock/Scs
+Include/ConfigBlock/Hda
+Include/ConfigBlock/Sata
+Include/ConfigBlock/Rst
+Include/ConfigBlock/Ieh
+Include/ConfigBlock/Me
+Include/ConfigBlock/PchDmi
+Include/ConfigBlock/Gpio
+Include/ConfigBlock/Dci
+Include/ConfigBlock/Cnvi
+Include/ConfigBlock/Gbe
+Include/ConfigBlock/TraceHub
+Include/ConfigBlock/Thc
+Include/ConfigBlock/Wdt
+Include/ConfigBlock/PcieRp/PchPcieRp
+Include/ConfigBlock/PcieRp
+Include/ConfigBlock/Psf
+Include/ConfigBlock/SerialIo
+Include/ConfigBlock/HybridStorage
+Include/ConfigBlock/Spi
+
+
+#
+# - Tcss
+Include/ConfigBlock/Tcss
+[Guids.common.Private]
+#
+# PCH
+#
+gPchDeviceTableHobGuid       = { 0xb3e123d0, 0x7a1e, 0x4db4, { 0xaf, 0x66, 0xbe, 0xd4, 0x1e, 0x9c, 0x66, 0x38 }}
+gWdtHobGuid                  = { 0x65675786, 0xacca, 0x4b11, { 0x8a, 0xb7, 0xf8, 0x43, 0xaa, 0x2a, 0x8b, 0xea }}
+gPchConfigHobGuid            = { 0x524ed3ca, 0xb250, 0x49f5, { 0x94, 0xd9, 0xa2, 0xba, 0xff, 0xc7, 0x0e, 0x14 }}
+gGpioLibUnlockHobGuid        = { 0xA7892E49, 0x0F9F, 0x4166, { 0xB8, 0xD6, 0x8A, 0x9B, 0xD9, 0x8B, 0x17, 0x38 }}
+gSiScheduleResetHobGuid      = { 0xEA0597FF, 0x8858, 0x41CA, { 0xBB, 0xC1, 0xFE, 0x18, 0xFC, 0xD2, 0x8E, 0x22 }}
+gCnviConfigHobGuid           = { 0xa8d6e4d9, 0x94b7, 0x4fc9, { 0x94, 0x3f, 0x7a, 0x9c, 0xb2, 0x31, 0x57, 0xce }}
+
+#
+# CPU
+#
+gPeiAcpiCpuDataGuid          = { 0x7682bbef, 0xb0b6, 0x4939, { 0xae, 0x66, 0x1b, 0x3d, 0xf2, 0xf6, 0xaa, 0xf3 }}
+gCpuStatusCodeDataTypeExceptionHandlerGuid = { 0x3BC2BD12, 0xAD2E, 0x11D5, { 0x87, 0xDD, 0x00, 0x06, 0x29, 0x45, 0xC3, 0xB9 }}
+
+#
+# SA
+#
+gSchemaListGuid              = { 0x3047C2AC, 0x5E8E, 0x4C55, { 0xA1, 0xCB, 0xEA, 0xAD, 0x0A, 0x88, 0x86, 0x1B }}
+gEqPhase3SchemaGuid          = { 0x145AC084, 0x340E, 0x4777, { 0xBC, 0x75, 0xF8, 0x50, 0x5F, 0xFD, 0x50, 0x9D }}
+gScoreSchemaGuid             = { 0x8233A1BB, 0x58D5, 0x4F66, { 0xA1, 0x3F, 0x8A, 0xA3, 0xED, 0x6A, 0xF5, 0xA0 }}
+gPortMarginGuid              = { 0xD7154D12, 0x03B2, 0x4054, { 0x8C, 0xD2, 0x9F, 0x4B, 0x20, 0x90, 0xBE, 0xF7 }}
+gJitterTolerenceGuid         = { 0xB52A2E04, 0x45FF, 0x484E, { 0xB5, 0xFE, 0xEE, 0x47, 0x8F, 0x5F, 0x6C, 0x9B }}
+gLaneMarginGuid              = { 0x7AC0996D, 0xA601, 0x4210, { 0x94, 0x4E, 0x93, 0x4E, 0x51, 0x7B, 0x6C, 0x57 }}
+gVocMarginGuid               = { 0x3578349A, 0x9E98, 0x4F70, { 0x91, 0xCB, 0xE2, 0x5B, 0x98, 0x99, 0xBC, 0x16 }}
+
+[Guids]
+gSmbiosProcessorInfoHobGuid        =  {0xe6d73d92, 0xff56, 0x4146, {0xaf, 0xac, 0x1c, 0x18, 0x81, 0x7d, 0x68, 0x71}}
+gSmbiosCacheInfoHobGuid            =  {0xd805b74e, 0x1460, 0x4755, {0xbb, 0x36, 0x1e, 0x8c, 0x8a, 0xd6, 0x78, 0xd7}}
+
+##
+## IntelFrameworkPkg
+##
+# MsegSmramPei.inf
+gEfiSmmPeiSmramMemoryReserveGuid   =  {0x6dadf1d1, 0xd4cc, 0x4910, {0xbb, 0x6e, 0x82, 0xb1, 0xfd, 0x80, 0xff, 0x3d}}
+##
+## MdeModulePkg
+##
+gEfiMemoryTypeInformationGuid  =  {0x4c19049f, 0x4137, 0x4dd3, {0x9c, 0x10, 0x8b, 0x97, 0xa8, 0x3f, 0xfd, 0xfa}}
+gEfiCapsuleVendorGuid  =  {0x711c703f, 0xc285, 0x4b10, {0xa3, 0xb0, 0x36, 0xec, 0xbd, 0x3c, 0x8b, 0xe2}}
+gEfiConsoleOutDeviceGuid = { 0xd3b36f2c, 0xd551, 0x11d4, { 0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d}}
+##
+## Common
+##
+## Include/ConfigBlock/SiConfig.h
+gSiConfigGuid = {0x4ed6d282, 0x22f3, 0x4fe1, {0xa6, 0x61, 0x6, 0x1a, 0x97, 0x38, 0x59, 0xd8}}
+##
+gSiPreMemConfigGuid = {0xb94c004c, 0xa0ab, 0x40f0, {0x9b, 0x61, 0x0b, 0x25, 0x88, 0xbe, 0xfd, 0xc6}}
+##
+##
+gPciePreMemConfigGuid = {0xd0f9c2a9, 0x7332, 0x4733, {0x8d, 0xb1, 0x98, 0x79, 0x27, 0x60, 0xda, 0xe6}}
+##
+gSiPkgTokenSpaceGuid  =  {0x977c97c1, 0x47e1, 0x4b6b, {0x96, 0x69, 0x43, 0x66, 0x99, 0xcb, 0xe4, 0x5b}}
+## Include/SiConfigHob.h
+gSiConfigHobGuid = {0xb3903068, 0x7482, 0x4424, {0xba, 0x4b, 0x40, 0x5f, 0x8f, 0xd7, 0x65, 0x4e}}
+gBootMediaHobGuid = {0x8c7340ea, 0xde8b, 0x4e06, {0xa4, 0x78, 0xec, 0x8b, 0x62, 0xd7, 0xa, 0x8b}}
+gEfiPramConfGuid = { 0xecb54cd9, 0xe5ae, 0x4fdc, { 0xa9, 0x71, 0xe8, 0x77, 0x75, 0x60, 0x68, 0xf7}}
+##
+##
+## IPU's GUIDs
+##
+gIpuDataHobGuid  = {0x61dd66, 0x212b, 0x4dae, {0x9b, 0xc0, 0x30, 0xe0, 0x2e, 0x3f, 0x40, 0xfd}}
+gIpuConfigHobGuid  = {0x446268e5, 0x8c30, 0x4e0a, {0x9b, 0x28, 0xa3, 0xe7, 0xf0, 0x4, 0x31, 0xd0}}
+
+## Include/FspErrorInfo.h
+gFspErrorInfoHobGuid = {0x611e6a88, 0xadb7, 0x4301, {0x93, 0xff, 0xe4, 0x73, 0x04, 0xb4, 0x3d, 0xa6}}
+gStatusCodeDataTypeFspErrorGuid = {0x611e6a88, 0xadb7, 0x4301, {0x93, 0xff, 0xe4, 0x73, 0x04, 0xb4, 0x3d, 0xa6}}
+
+##
+##
+## SystemAgent
+##
+gSaOverclockingPreMemConfigGuid  =  { 0x09ecc29d, 0xdbbe, 0x49fb, { 0xa6, 0x49, 0x4b, 0xf6, 0x40, 0xe2, 0xeb, 0xd6}}
+gSaAcpiTableStorageGuid  =  {0x3c0ed5e2, 0x91ea, 0x4b94, { 0x82, 0xd, 0x9d, 0xaf, 0x9a, 0x3b, 0xb4, 0xa2}}
+gSaDataHobGuid  =  {0xe07d0bda, 0xbf90, 0x46a9, { 0xb0, 0x0e, 0xb2, 0xc4, 0x4a, 0x0e, 0xd6, 0xd0}}
+gPsmiDataHobGuid  =  {0xa9652bd, 0x6acd, 0x47e5, { 0x80, 0x3a, 0x9, 0x53, 0x7b, 0xd2, 0xa8, 0x48 }}
+gSaConfigHobGuid  = {0x762fa2e6, 0xea3b, 0x41c8, { 0x8c, 0x52, 0x63, 0x76, 0x6d, 0x70, 0x39, 0xe0}}
+gCpuPcieHobGuid  = {0x440ab2e5, 0xa3ea, 0x466f, { 0x84, 0x96, 0xdf, 0xb1, 0x3b, 0x75, 0x29, 0x95}}
+gSaPegHobGuid    = {0x5807c388, 0xfa06, 0x4683, { 0xab, 0xd3, 0x1b, 0x31, 0xbb, 0x81, 0x2d, 0x23}}
+gHgAcpiTableStorageGuid  =  {0x8de8964f, 0x2939, 0x4b49, { 0xa3, 0x48, 0xf6, 0xb2, 0xb2, 0xde, 0x4a, 0x42}}
+gSaSsdtAcpiTableStorageGuid  =  {0xca89914d, 0x2317, 0x452e, { 0xb2, 0x45, 0x36, 0xc6, 0xfb, 0x77, 0xa9, 0xc6}}
+gSegSsdtAcpiTableStorageGuid  =  {0x10c3800d, 0xe225, 0x480e, { 0x85, 0xda, 0xbe, 0xed, 0xdb, 0x88, 0xe1, 0xc6}}
+gHgAcpiTablePchStorageGuid  =  {0xe3164526, 0x690a, 0x4e0d, { 0xb0, 0x28, 0xae, 0xa1, 0x6f, 0xe2, 0xbc, 0xf3}}
+gSaMiscPeiPreMemConfigGuid  =  {0x4a525577, 0x3469, 0x4f11, { 0x99, 0xcf, 0xfb, 0xcd, 0x5e, 0xf1, 0x84, 0xe4}}
+gSaMiscPeiConfigGuid  =  {0x1def8e6, 0xe998, 0x4e27, { 0x89, 0x98, 0x9c, 0xfa, 0xb2, 0x92, 0xbc, 0x50}}
+gCpuPciePeiPreMemConfigGuid  =  { 0x81baf3c9, 0xf295, 0x4572, { 0x8b, 0x21, 0x79, 0x3f, 0xa3, 0x1b, 0xa5, 0xdb}}
+gCpuDmiPreMemConfigGuid  =  { 0x30d12ad5, 0xa3c6, 0x49c7, { 0xa2, 0xfd, 0x35, 0x5c, 0xcb, 0x61, 0xcb, 0xcf}}
+gVmdPeiConfigGuid = { 0x79b52c74, 0xb9ba, 0x4f36, {0xa2, 0x40, 0xf2, 0x41, 0x0d, 0x20, 0x84, 0x8a}}
+gVmdInfoHobGuid            = { 0xccd0306e, 0x7fa1, 0x4df5, {0x99, 0x99, 0xc1, 0xf8, 0x9a, 0x1d, 0x1b, 0xa9}}
+gEfiVmdFeatureVariableGuid = { 0x61a14fe8, 0x4dab, 0x4a19, {0xb1, 0xe3, 0x97, 0xfb, 0x23, 0xd0, 0x92, 0x12}}
+gPramPreMemConfigGuid  =  { 0xcf0b9b31, 0xa1a6, 0x46d9, { 0x8d, 0x14, 0xe3, 0xac, 0x69, 0x0f, 0x52, 0x3a}}
+gHybridGraphicsConfigGuid  =  { 0xc7956998, 0xc065, 0x46c4, { 0x8e, 0x2f, 0x58, 0x2b, 0x67, 0xeb, 0xbe, 0x2f}}
+gHybridGraphicsInfoHobGuid =  { 0x46cbed07, 0x717a, 0x4a75, { 0x85, 0xb3, 0xf4, 0xb6, 0xc4, 0xe2, 0x3a, 0x75}}
+gMemoryConfigGuid  =  { 0x26cf084c, 0xc9db, 0x41bb, { 0x92, 0xc6, 0xd1, 0x97, 0xb8, 0xa1, 0xe4, 0xbf}}
+gMemoryConfigNoCrcGuid  =  { 0xc56c73d0, 0x1cdb, 0x4c0c, { 0xa9, 0x57, 0xea, 0x62, 0xa9, 0xe6, 0xf5, 0x0c}}
+gGnaConfigGuid  =  { 0x53e0ef18, 0xb8a8, 0x4795, { 0xa6, 0x6d, 0xe4, 0x77, 0x2c, 0xc3, 0xae, 0x82}}
+gVtdDxeConfigGuid  =  {0xcbbf1996, 0x4a4c, 0x4dd9, {0xab, 0xbe, 0x83, 0x89, 0x73, 0xd, 0x48, 0xb0}}
+gPcieDxeConfigGuid  =  {0x1ed2d6f1, 0xa9d2, 0x476e, {0x8e, 0x74, 0xad, 0xd9, 0x5b, 0x5,  0x10, 0x82}}
+gMemoryDxeConfigGuid  =  {0xa5c7dda8, 0x686b, 0x404f, {0x86, 0x40, 0xf8, 0x2,  0xd,  0x84, 0x4c, 0x94}}
+gFspReservedMemoryResourceHobTsegGuid  =  { 0xd038747c, 0xd00c, 0x4980, { 0xb3, 0x19, 0x49, 0x01, 0x99, 0xa4, 0x7d, 0x55}}
+gCpuPcieRpPrememConfigGuid = { 0x41aef892, 0xc800, 0x4ac0, {0xa9, 0x30, 0x84, 0xac, 0x47, 0xca, 0xca, 0x7e}}
+gCpuPcieRpConfigGuid = { 0x9749a5fb, 0x9130, 0x44f0, {0x8f, 0x61, 0xdb, 0xff, 0x8e, 0xf2, 0xca, 0xc7}}
+## Include/Guid/AcpiS3Context.h
+gEfiAcpiVariableGuid  =  {0xaf9ffd67, 0xec10, 0x488a, {0x9d, 0xfc, 0x6c, 0xbf, 0x5e, 0xe2, 0x2c, 0x2e}}
+## IntelFsp2Pkg/IntelFsp2Pkg.dec gSiMemoryS3DataGuid is the same as gFspNonVolatileStorageHobGuid
+gSiMemoryS3DataGuid       = { 0x721acf02, 0x4d77, 0x4c2a, { 0xb3, 0xdc, 0x27, 0x0b, 0x7b, 0xa9, 0xe4, 0xb0 } }
+gSiMemoryInfoDataGuid     = { 0x9b2071d4, 0xb054, 0x4e0c, { 0x8d, 0x09, 0x11, 0xcf, 0x8b, 0x9f, 0x03, 0x23 } }
+gSiMemoryPlatformDataGuid = { 0x6210d62f, 0x418d, 0x4999, { 0xa2, 0x45, 0x22, 0x10, 0x0a, 0x5d, 0xea, 0x44 } }
+## Include/MrcRmtData.h
+gEfiMemorySchemaGuid  = { 0xCE3F6794, 0x4883, 0x492C, { 0x8D, 0xBA, 0x2F, 0xC0, 0x98, 0x44, 0x77, 0x10}}
+gMrcSchemaListHobGuid = { 0x3047C2AC, 0x5E8E, 0x4C55, { 0xA1, 0xCB, 0xEA, 0xAD, 0x0A, 0x88, 0x86, 0x1B}}
+gRmtResultMetadataGuid = { 0x02CB1552, 0xD659, 0x4232, { 0xB5, 0x1F, 0xCA, 0xB1, 0xE1, 0x1F, 0xCA, 0x87}}
+gRmtResultColumnsGuid  = { 0x0E60A1EB, 0x331F, 0x42A1, { 0x9D, 0xE7, 0x45, 0x3E, 0x84, 0x76, 0x11, 0x54}}
+gMargin2DResultMetadataGuid = { 0x48265582, 0x8E49, 0x4AC7, { 0xAA, 0x06, 0xE1, 0xB9, 0xA7, 0x4C, 0x97, 0x16}}
+gMargin2DResultColumnsGuid  = { 0x91A449EC, 0x8A4A, 0x4736, { 0xAD, 0x71, 0xA3, 0xF6, 0xF6, 0xD7, 0x52, 0xD9}}
+gSaFspErrorTypePeiGopInit = { 0x8106a5cc, 0x30ba, 0x41cf, { 0xa1, 0x78, 0x63, 0x38, 0x91, 0x11, 0xae, 0xb2}}
+gSaFspErrorTypePeiGopGetMode = { 0x348cc7fe, 0x1e9a, 0x4c7a, { 0x86, 0x28, 0xae, 0x48, 0x5b, 0x42, 0x10, 0xf0}}
+gSaFspErrorTypeCallerId = { 0x98230916, 0xe632, 0x49ff, { 0x81, 0x81, 0x55, 0xce, 0xe5, 0x10, 0x36, 0x89}}
+gMrcFspErrorTypeCallerId = { 0x5a47c211, 0x642f, 0x4f92, { 0x9c, 0xb3, 0x7f, 0xeb, 0x93, 0xda, 0xdd, 0xba}}
+gMrcFspErrorTypeMemoryInit = { 0x5de1c071, 0x2c9c, 0x4a53, { 0x80, 0x21, 0x4e, 0x80, 0xd2, 0x5d, 0x44, 0xa8}}
+gSaPciePeiConfigGuid = { 0xdaa929a9, 0x5ec9, 0x486a, { 0xb0, 0xf7, 0x82, 0x3a, 0x55, 0xc7, 0xb5, 0xb3}}
+gSaPciePeiPreMemConfigGuid = { 0xfc5e01a3, 0x69f6, 0x4e35, { 0x9f, 0xcf, 0x6, 0x68, 0x7b, 0xab, 0x31, 0xd7}}
+
+
+#
+# Host Bridge
+#
+gHostBridgePeiPreMemConfigGuid  =  {0xbdef6805, 0x2080, 0x44ad, { 0x93, 0x2e, 0x00, 0x04, 0xf5, 0x2c, 0xb7, 0xa1}}
+gHostBridgePeiConfigGuid  =  {0x3b6d998e, 0x8b6e, 0x4f53, { 0xbe, 0x41, 0x7, 0x41, 0x95, 0x53, 0x8a, 0xaf}}
+gHostBridgeDataHobGuid  =  {0x3b682d57, 0xd402, 0x40a6, { 0xb1, 0x34, 0xa0, 0xc4, 0xf6, 0x31, 0x1d, 0x9}}
+
+#
+# Graphics
+#
+gGraphicsPeiPreMemConfigGuid  =  {0x0319c56b, 0xc43a, 0x42f1, { 0x80, 0xbe, 0xca, 0x5b, 0xd1, 0xd5, 0xc9, 0x28}}
+gGraphicsPeiConfigGuid  =  {0x04249ac0, 0x0088, 0x439f, { 0xa7, 0x4e, 0xa7, 0x04, 0x2a, 0x06, 0x2f, 0x5d}}
+gGraphicsDxeConfigGuid  =  {0x34d93161, 0xf78e, 0x4915, {0xad, 0xc4, 0xdb, 0x67, 0x16, 0x42, 0x39, 0x24}}
+gGraphicsAcpiTableStorageGuid  =  {0xce9caa0e, 0x8248, 0x442c, { 0x9e, 0x57, 0x50, 0xf2, 0x12, 0xe2, 0xba, 0xed}}
+## IpBlock/Graphics/IncludePrivate/GraphicsDataHob.h
+gGraphicsDataHobGuid = { 0x48e6e20a, 0x9110, 0x4332, { 0x8c, 0x9f, 0x5f, 0x7c, 0xae, 0x76, 0xfc, 0xf3}}
+
+#
+# IPU
+#
+gIpuPreMemConfigGuid  =  { 0x830a222b, 0x3ff5, 0x432e, { 0x9d, 0xd5, 0x4e, 0xe3, 0xfc, 0xa2, 0xaa, 0xa2}}
+gIpuAcpiTableStorageGuid  =  {0x9b25dba6, 0x45b3, 0x4190, { 0x99, 0x8d, 0xaf, 0x31, 0xdc, 0x21, 0x78, 0x21}}
+
+## Include/SsaCommonConfig.h
+gSsaPostcodeHookGuid = {0xADF0A27B, 0x61A6, 0x4F18, {0x9E, 0xAC, 0x46, 0x87, 0xE7, 0x9E, 0x6F, 0xBB}}
+gSsaBiosVariablesGuid = {0x43eeffe8, 0xa978, 0x41dc, {0x9d, 0xb6, 0x54, 0xc4, 0x27, 0xf2, 0x7e, 0x2a}}
+gSsaBiosResultsGuid = {0x8f4e928, 0xf5f, 0x46d4, {0x84, 0x10, 0x47, 0x9f, 0xda, 0x27, 0x9d, 0xb6}}
+gHobUsageDataGuid = {0xc764a821, 0xec41, 0x450d, { 0x9c, 0x99, 0x27, 0x20, 0xfc, 0x7c, 0xe1, 0xf6 }}
+##
+## TBT
+##
+gPeiITbtConfigGuid            =  {0xd7e7e1e6, 0xcbec, 0x4f5f, {0xae, 0xd3, 0xfd, 0xc0, 0xa8, 0xb0, 0x7e, 0x25}}
+gDxeITbtConfigGuid            =  {0x196bf9e3, 0x20d7, 0x4b7b, {0x89, 0xf9, 0x31, 0xc2, 0x72, 0x08, 0xc9, 0xb9}}
+gITbtInfoHobGuid              =  {0x74a81eaa, 0x033c, 0x4783, {0xbe, 0x2b, 0x84, 0x85, 0x74, 0xa6, 0x97, 0xb7}}
+
+##
+## TCSS
+##
+gTcssHobGuid  = { 0x455702ce, 0x4adb, 0x45d9, { 0x8b, 0x27, 0xf7, 0xb0, 0xd9, 0x79, 0x8a, 0xe0}}
+gTcssSsdtAcpiTableStorageGuid  =  { 0xbd53572c, 0x6486, 0x45e2, { 0x90, 0xe, 0xb9, 0x8a, 0xc1, 0xa8, 0x25, 0x45}}
+gTcssPeiConfigGuid =  { 0xfb631590, 0x79c9, 0x4f0d, { 0xa9, 0x96, 0xee, 0xe2, 0x98, 0x66, 0xfa, 0xfd}}
+gTcssPeiPreMemConfigGuid = { 0x514ed829, 0xb2bb, 0x46be, { 0xa9, 0x78, 0x6d, 0xc, 0x91, 0xc1, 0xeb, 0xe4}}
+gTcssSsidHobGuid  = { 0x8903d47a, 0x8f82, 0x4063, { 0xa8, 0x40, 0x31, 0x68, 0x9c, 0x9e, 0x78, 0x20}}
+##
+## Telemetry
+##
+gTelemetryPeiConfigGuid       =  { 0x8ebf9fee, 0x7496, 0x42b4, { 0xa6, 0xf6, 0xcf, 0x2b, 0x33, 0x99, 0x30, 0xd6}}
+gTelemetryPeiPreMemConfigGuid =  { 0x422de269, 0xb2ef, 0x4829, { 0x93, 0x36, 0x0b, 0xe4, 0x98, 0xb5, 0x53, 0xb2}}
+
+##
+## VTD
+##
+gVtdDataHobGuid  = {0x1d60dce8, 0x503a, 0x44a8, { 0xb3, 0x2d, 0x56, 0xb3, 0x88, 0xf3, 0x4c, 0x55}}
+gVtdConfigGuid  =  {0x03e5cf63, 0xbebb, 0x4041, { 0xb7, 0xe7, 0xbf, 0x54, 0x61, 0x20, 0xf1, 0xc5}}
+
+#
+# TRACEHUB
+#
+gCpuTraceHubPreMemConfigGuid =  { 0xf2e17477, 0x93f3, 0x430d, { 0x9e, 0x08, 0x3c, 0xcc, 0x6e, 0x2f, 0x6c, 0x4b}}
+gTraceHubDataHobGuid         =  { 0xf1187e54, 0x995f, 0x49d9, { 0xac, 0xee, 0xc5, 0x34, 0xf4, 0x5a, 0x18, 0xc7}}
+
+##
+## Cpu
+##
+gSmramCpuDataHeaderGuid  =  {0x5848fd2d, 0xd6af, 0x474b, {0x82, 0x75, 0x95, 0xdd, 0xe7, 0x0a, 0xe8, 0x23}}
+gCpuAcpiTableStorageGuid  =  {0xc38fb0e2, 0x0c43, 0x49c9, {0xb5, 0x44, 0x9b, 0x17, 0xaa, 0x4d, 0xcb, 0xa3}}
+gTxtInfoHobGuid  =  {0x2986883f, 0x88e0, 0x48d0, {0x4b, 0x82, 0x20, 0xc2, 0x69, 0x48, 0xdd, 0xac}}
+gHtBistHobGuid  =  {0xbe644001, 0xe7d4, 0x48b1, {0xb0, 0x96, 0x8b, 0xa0, 0x47, 0xbc, 0x7a, 0xe7}}
+gProcessorProducerGuid  =  {0x1bf06aea, 0x5bec, 0x4a8d, {0x95, 0x76, 0x74, 0x9b, 0x09, 0x56, 0x2d, 0x30}}
+gCpuInitDataHobGuid  =  {0x266e31cc, 0x13c5, 0x4807, {0xb9, 0xdc, 0x39, 0xa6, 0xba, 0x88, 0xff, 0x1a}}
+gBiosGuardHobGuid  =  {0x66f0c42d, 0x0d0e, 0x4c23, {0x93, 0xc0, 0x2d, 0x52, 0x95, 0xdc, 0x5e, 0x21}}
+gCpuSecurityPreMemConfigGuid = {0xfd5c346, 0x8260, 0x4067, {0x94, 0x69, 0xcf, 0x91, 0x68, 0xa3, 0x42, 0x90}}
+gCpuConfigLibPreMemConfigGuid = {0xfc1c0ec2, 0xc6b4, 0x4f05, {0xbb, 0x85, 0xc8, 0x0, 0x8d, 0x5b, 0x4a, 0xb7}}
+gCpuTxtPreMemConfigGuid = {0x20b4db03, 0xd160, 0x4f83, {0xa4, 0x1, 0x9a, 0x8a, 0xa8, 0x88, 0x68, 0x14}}
+gCpuTestConfigGuid = {0xd4dba957, 0xd9c, 0x4af2, {0x9d, 0x40, 0x35, 0xa8, 0x44, 0xe4, 0x93, 0xad}}
+gBiosGuardConfigGuid = {0x762f9ddb, 0x1c89, 0x4612, {0x84, 0x6b, 0xee, 0xdc, 0x8f, 0x62, 0x25, 0x45}}
+gCpuConfigGuid = {0x48c3aac9, 0xd66c, 0x42e4, {0x9b, 0x1d, 0x39, 0x4, 0x5f, 0x46, 0x53, 0x41}}
+gCpuPidTestConfigGuid = {0x2511095f, 0xd49e, 0x4537, {0xa6, 0x60, 0x88, 0x71, 0x31, 0xd1, 0x53, 0xda}}
+gCpuPowerMgmtBasicConfigGuid = {0xa021e31d, 0x7c14, 0x47da, {0xb5, 0xec, 0xca, 0xbb, 0x4d, 0x76, 0xed, 0xc8}}
+gCpuPowerMgmtCustomConfigGuid = {0x562fa1c8, 0x55ee, 0x4e2f, {0x91, 0xca, 0x8d, 0x84, 0x50, 0x3, 0x2f, 0xe}}
+gCpuPowerMgmtPsysConfigGuid = {0x4e7f850, 0x19b5, 0x47ba, {0x9d, 0x28, 0xb1, 0xe7, 0x5e, 0x1f, 0x48, 0x53}}
+gCpuPowerMgmtTestConfigGuid = {0x5161ed3d, 0x90bf, 0x436f, {0xb8, 0x33, 0xd7, 0x17, 0x89, 0xb3, 0x48, 0xc1}}
+gCpuPowerMgmtVrConfigGuid = {0x254766c9, 0x929d, 0x4eac, {0x9e, 0xec, 0xdf, 0xa2, 0x2, 0x44, 0xb5, 0xea}}
+gTxtPrivateBaseHobGuid = {0x651EBDB4, 0x4E1D, 0x422A, {0x82, 0xFB, 0x1E, 0xDA, 0x66, 0x71, 0x6C, 0x0B}}
+gTxtAcmInfoTableGuid = {0x7FC03AAA, 0x46A7, 0x18DB, {0x2E, 0xAC, 0x69, 0x8F, 0x8D, 0x41, 0x7F, 0x5A}}
+gOverclockingPreMemConfigGuid = {0xad151bbc, 0xd5a0, 0x481e, {0x9d, 0x19, 0xf6, 0x7b, 0x79, 0xe9, 0x8f, 0x68}}
+gCpuDataHobGuid = {0x1eec629f, 0xf3cf, 0x4b02, { 0xa9, 0xa5, 0x27, 0xa2, 0x33, 0x20, 0xbe, 0x5d}}
+
+##
+## Me
+##
+gMePlatformReadyToBootGuid  =  {0x03fdf171, 0x1d67, 0x4ace, {0xa9, 0x04, 0x3e, 0x36, 0xd3, 0x38, 0xfa, 0x74}}
+gMeSsdtAcpiTableStorageGuid  =  {0x9a8f82d5, 0x39b1, 0x48da, {0x92, 0xdc, 0xa2, 0x2d, 0xa8, 0x83, 0x4d, 0xf6}}
+gMeDataHobGuid  =  {0x1e94f097, 0x5acd, 0x4089, {0xb2, 0xe3, 0xb9, 0xa5, 0xc8, 0x79, 0xa7, 0x0c}}
+gMeEDebugHobGuid = {0x5f672ec1, 0xa8f6, 0x47d3, {0x9c, 0xd0, 0x92, 0xe9, 0xe9, 0xe0, 0xb3, 0x84}}
+gPciImrHobGuid  =  {0x49b1eac3, 0x0cd6, 0x451e, {0x96, 0x30, 0x92, 0x4b, 0xc2, 0x69, 0x35, 0x86}}
+gTpm2AcpiTableStorageGuid  =  {0x7d279373, 0xeecc, 0x4d4f, {0xae, 0x2f, 0xce, 0xc4, 0xb7, 0x06, 0xb0, 0x6a}}
+gMeBiosPayloadHobGuid  =  {0x992c52c8, 0xbc01, 0x4ecd, {0x20, 0xbf, 0xf9, 0x57, 0x16, 0x0e, 0x9e, 0xf7}}
+gEfiTouchPanelGuid  =  {0x91b1d27b, 0xe126, 0x48d1, {0x82, 0x34, 0xd2, 0x8b, 0x81, 0xc8, 0x83, 0x62}}
+gMeFwHobGuid  = {0x52885e62, 0x4c4d, 0x9546, {0x2d, 0xba, 0x2a, 0x84, 0x89, 0xee, 0xa8, 0xa3 }}
+gMePeiPreMemConfigGuid  =  {0x67ed113b, 0xd4ab, 0x43f5, {0x9c, 0x3c, 0x35, 0x44, 0x15, 0xaa, 0x47, 0x5c}}
+gMePeiConfigGuid  =  {0x9bad5628, 0x657b, 0x48e3, {0xb1, 0x11, 0xc3, 0xb9, 0xeb, 0xea, 0xee, 0x17}}
+gMeDxeConfigGuid  =  {0xad08bacc, 0x4906, 0x4d9b, {0xbe, 0xd1, 0x81, 0xa5, 0x2c, 0x13, 0xdb, 0xf8}}
+gIvmProtocolGuid  = {0x3C4852D6, 0xD47B, 0x4F46, {0xB0, 0x5E, 0xB5, 0xED, 0xC1, 0xAA, 0x44, 0x0E}}
+gSdmProtocolGuid  = {0xDBA4D603, 0xD7ED, 0x4931, {0x88, 0x23, 0x17, 0xAD, 0x58, 0x57, 0x05, 0xD5}}
+gRtmProtocolGuid  = {0x5565A099, 0x7FE2, 0x45C1, {0xA2, 0x2B, 0xD7, 0xE9, 0xDF, 0xEA, 0x9A, 0x2E}}
+gSvmProtocolGuid  = {0xF47ACC04, 0xD94B, 0x49CA, {0x87, 0xA6, 0x7F, 0x7D, 0xC0, 0x3F, 0xBA, 0xF3}}
+gMeEopDoneHobGuid = {0x247323af, 0xc8f1, 0x4b8c, {0x90, 0x87, 0xaa, 0x4b, 0xa7, 0xb7, 0x6d, 0x6a}}
+gMePreMemPolicyHobGuid = {0xe6de74a5, 0x21b, 0x4f78, {0xa3, 0xcd, 0x34, 0xd6, 0x7e, 0xe4, 0x82, 0xbf}}
+gMePolicyHobGuid =  {0x0341cf17, 0xbc8f, 0x4a20, {0xac, 0x28, 0x6c, 0x3c, 0x32, 0x4c, 0xd4, 0x17}}
+gMeFspErrorTypeEop = {0x948585c4, 0x76a4, 0x45bb, {0xbe, 0x6c, 0x39, 0x61, 0xc3, 0xab, 0xde, 0x15}}
+gMeFspErrorTypeCallerId = {0x1f4dc7e9, 0x26ca, 0x4336, { 0x8c, 0xe3, 0x39, 0x31, 0x3, 0xb5, 0xf3, 0xd7}}
+gMeConfigSpaceGuid = {0xcb405fd3, 0x4404, 0x4ccd, {0x85, 0x18, 0x0d, 0x03, 0x07, 0x48, 0xd0, 0xa6}}
+gMeDidSentHobGuid = {0x4c3d3af1, 0x1720, 0x4c3f, {0xab, 0x7c, 0x36, 0x50, 0xbb, 0x5b, 0x85, 0x7e}}
+gMeDisabledEventHobGuid = {0x1500b6a7, 0xb82f, 0x456b, {0xba, 0x2b, 0x4, 0x72, 0x41, 0x6, 0xf, 0x7}}
+gMeSavedPmconHobGuid = {0xb8baee93, 0xea15, 0x4ddc, {0x90, 0xb8, 0x44, 0x12, 0xd2, 0xea, 0xcf, 0x4f}}
+
+##
+## Amt
+##
+gAmtForcePushPetPolicyGuid  =  {0xacc8e1e4, 0x9f9f, 0x4e40, {0xa5, 0x7e, 0xf9, 0x9e, 0x52, 0xf3, 0x4c, 0xa5}}
+gAmtForcePushPetVariableGuid  =  {0xd7ac94af, 0xa498, 0x45ec, {0xbf, 0xa2, 0xa5, 0x6e, 0x95, 0x34, 0x61, 0x8b}}
+gMeBiosExtensionSetupGuid  =  {0xaf013532, 0xc828, 0x4fbd, {0x20, 0xae, 0xfe, 0xe6, 0xaf, 0xbe, 0xdd, 0x4e}}
+gAmtPetQueueHobGuid  =  {0xca0801d3, 0xafb1, 0x4dec, {0x9b, 0x65, 0x93, 0x65, 0xec, 0xc7, 0x93, 0x6b}}
+gAmtForcePushPetHobGuid  =  {0x4efa0db6, 0x26dc, 0x4bb1, {0xa7, 0x6f, 0x14, 0xbc, 0x63, 0x0c, 0x7b, 0x3c}}
+gAmtPeiConfigGuid  =  {0x7254546a, 0xace3, 0x4a32, {0x9a, 0xc2, 0xf0, 0xcc, 0x28, 0x4e, 0x1e, 0x4d}}
+gAmtDxeConfigGuid  =  {0x3f12ab6b, 0xb04d, 0x4824, {0xbf, 0xb6, 0x3e, 0xe7, 0x5d, 0x02, 0x0b, 0x84}}
+gAmtPolicyHobGuid = {0x703eb2cd, 0x5ca8, 0x4233, {0x9d, 0xa3, 0x0d, 0x2d, 0x57, 0xe6, 0x73, 0x34}}
+gAmtMebxDataGuid  = { 0x912e1538, 0x371d, 0x4ea6, { 0xa8, 0x41, 0xd7, 0x6a, 0x8, 0x93, 0x3a, 0x70}}
+
+##
+## PCH
+##
+gEfiSmbusArpMapGuid  =  {0x707be83e, 0x0bf6, 0x40a5, {0xbe, 0x64, 0x34, 0xc0, 0x3a, 0xa0, 0xb8, 0xe2}}
+gIrmtAcpiTableStorageGuid  =  {0x6684d675, 0xee06, 0x49b2, {0x87, 0x6f, 0x79, 0xc5, 0x8f, 0xdd, 0xa5, 0xb7}}
+gPchGlobalResetGuid  =  { 0x9db31b4c, 0xf5ef, 0x48bb, { 0x94, 0x2b, 0x18, 0x1f, 0x7e, 0x3a, 0x3e, 0x40 }}
+gI2c0MasterGuid  =  {0xa121a5db, 0xb0cb, 0x46ec, {0xa0, 0xcb, 0x27, 0xf8, 0xda, 0x72, 0xd4, 0x0e}}
+gI2c1MasterGuid  =  {0x55e3d0f9, 0xc954, 0x422d, {0x9c, 0x4c, 0xcc, 0x46, 0x12, 0x7c, 0x5b, 0xa8}}
+gI2c2MasterGuid  =  {0x9289aa40, 0xdf32, 0x474e, {0xb0, 0x3a, 0xc7, 0x7f, 0x76, 0xd3, 0x45, 0x21}}
+gI2c3MasterGuid  =  {0xd8b2c17f, 0x4117, 0x4166, {0x90, 0x17, 0x01, 0x68, 0xb4, 0x81, 0xac, 0x18}}
+gI2c4MasterGuid  =  {0x513d943d, 0x15d9, 0x4bd0, {0xb1, 0x41, 0x14, 0x50, 0x2b, 0xbf, 0xa9, 0xf2}}
+gI2c5MasterGuid  =  {0x50df382a, 0xb6bf, 0x4435, {0xae, 0xe6, 0x21, 0xf4, 0x85, 0x7c, 0xa8, 0xb4}}
+gChipsetInitHobGuid  =  {0xc1392859, 0x1f75, 0x446e, {0xb3, 0xf5, 0x83, 0x35, 0xfc, 0xc8, 0xd1, 0xc4}}
+
+gPchGeneralPreMemConfigGuid  = {0xC65F62FA, 0x52B9, 0x4837, {0x86, 0xEB, 0x1A, 0xFB, 0xD4, 0xAD, 0xBB, 0x3E}}
+gDciPreMemConfigGuid  =   {0xAB4AF366, 0x2250, 0x40C3, {0x92, 0xDB, 0x36, 0x61, 0xC6, 0x71, 0x3C, 0x5A}}
+gWatchDogPreMemConfigGuid  =  {0xFBCE08CC, 0x60F2, 0x4BDF, {0xB7, 0x88, 0x09, 0xBB, 0x81, 0x65, 0x52, 0x2B}}
+gPchTraceHubPreMemConfigGuid  = {0x8456c11, 0xdb85, 0x4914, {0x8d, 0x1a, 0xe5, 0xac, 0x64, 0x37, 0xe8, 0x96}}
+gPcieRpPreMemConfigGuid  =  {0x8377AB38, 0xF8B0, 0x476A, { 0x9C, 0xA1, 0x68, 0xEA, 0x78, 0x57, 0xD8, 0x2A}}
+gSmbusPreMemConfigGuid  =  {0x77A6E62C, 0x716B, 0x4386, {0x9E, 0x9C, 0x23, 0xA0, 0x2E, 0x13, 0x7B, 0x3A}}
+gLpcPreMemConfigGuid  =  {0xA6E6032F, 0x1E58, 0x407E, {0x9A, 0xB8, 0xC6, 0x30, 0xC6, 0xC4, 0x11, 0x8E}}
+gHsioPciePreMemConfigGuid  =  {0xE8FB0C12, 0x0DA1, 0x4A20, {0xB3, 0x36, 0xFB, 0x75, 0x93, 0x8C, 0xE0, 0x14}}
+gHsioSataPreMemConfigGuid  =  {0x732260D0, 0xA5C1, 0x4119, {0xAA, 0x0C, 0x93, 0xDC, 0xAC, 0x67, 0x0A, 0x31}}
+
+gPchGeneralConfigGuid  =  {0x6ED94C8C, 0x25F7, 0x4686, {0xB2, 0x46, 0xCA, 0x4D, 0xE2, 0x95, 0x4B, 0x5D}}
+gPchPcieConfigGuid  =  {0x0A53B507, 0x988B, 0x475C, {0xBF, 0x76, 0x33, 0xDE, 0x10, 0x6D, 0x94, 0x84}}
+gPchPcieRpDxeConfigGuid  =  {0x475530EA, 0xBD72, 0x416F, {0x98, 0x9F,0x48, 0x70, 0x5F, 0x14, 0x4E, 0xD9}}
+gSataConfigGuid  =  {0xF5F87B4F, 0xCC3C, 0x408D, {0x89, 0xE3, 0x61, 0xC5, 0x9C, 0x54, 0x07, 0xC4}}
+gRstConfigGuid = {0x43B6F112, 0x3851, 0x4DDC, {0x81, 0xB9, 0xE4, 0x5A, 0x2B, 0xE, 0xB3, 0x25}}
+gIoApicConfigGuid  =  {0x2873D0F1, 0x00F6, 0x40AB, {0xAC, 0x36, 0x9A, 0x68, 0xBA, 0x87, 0x3E, 0x6C}}
+gPchDmiConfigGuid  =  {0xB3A61210, 0x1CD3, 0x4797, {0x8E, 0xE6, 0xD3, 0x42, 0x9C, 0x4F, 0x17, 0xBD}}
+gFlashProtectionConfigGuid  =  {0xD0F71512, 0x9E32, 0x4CC9, {0xA5, 0xA3, 0xAD, 0x67, 0x9A, 0x06, 0x67, 0xB8}}
+gHdAudioPreMemConfigGuid  =  {0xD38F1E2B, 0x21B3, 0x43D1, {0x9F, 0xA8, 0xA5, 0xE1, 0x78, 0x73, 0x1E, 0x88}}
+gHdAudioConfigGuid  =  {0x7EB3CE7E, 0x82E0, 0x4CD7, {0xBD, 0xE5, 0xB2, 0xBF, 0x4E, 0x91, 0xC3, 0x4C}}
+gHdAudioDxeConfigGuid  =  {0x22EFC2DE, 0x66EB, 0x412D, {0x97, 0x17, 0xE7, 0x7A, 0xA1, 0x4E, 0x87, 0x76}}
+gInterruptConfigGuid  =  {0x09A2B815, 0xBE29, 0x45EF, {0xBF, 0xBF, 0x58, 0xEA, 0xAC, 0x5E, 0x29, 0x78}}
+gIshPreMemConfigGuid  =  {0x7C24E649, 0xC1F0, 0x4CF9, {0x87, 0x96, 0xE7, 0xA0, 0xEE, 0x34, 0x43, 0xF8}}
+gIshConfigGuid  =  {0x433AE2AA, 0xC5A6, 0x46ED, {0x94, 0x19, 0x1E, 0x5D, 0xB8, 0x1C, 0x57, 0x40}}
+gGbeConfigGuid  =  {0x4B2DE99E, 0x7517, 0x4D04, {0x8C, 0x02, 0xF1, 0x1A, 0x59, 0x2B, 0x14, 0x2F}}
+gTsnConfigGuid  =  {0x9E9A93CB, 0x0F4E, 0x4E56, {0x90, 0x2D, 0x6C, 0x76, 0xDE, 0x90, 0xF7, 0x71}}
+gLockDownConfigGuid  =  {0x8A838E0A, 0xA639, 0x46F0, {0xA9, 0xCE, 0x70, 0xC4, 0x85, 0xFB, 0xA8, 0x0D}}
+gP2sbConfigGuid  =  {0x2474DCB8, 0x4BB4, 0x49DA, {0x87, 0x83, 0x7C, 0xD3, 0xD3, 0x85, 0xFF, 0x07}}
+gPmConfigGuid  =  {0x93826157, 0xDC85, 0x4E34, {0xAE, 0xD9, 0x6E, 0xA1, 0x0D, 0xF9, 0xE3, 0xA7}}
+gScsConfigGuid  =  {0xF4DE6D52, 0xB5C9, 0x48C0, {0xA0, 0x4A, 0x68, 0x54, 0x20, 0x94, 0x05, 0xD0}}
+gScsInfoHobGuid = {0x94C5E85B, 0xAA6D, 0x481D, {0x8B, 0xBD, 0x54, 0xAA, 0xE2, 0x99, 0x78, 0xB2}}
+gSdCardConfigGuid = {0xD6A3038E, 0x50AE, 0x44B0, {0x93, 0xE2, 0xF7, 0x93, 0xF5, 0x90, 0x50, 0x27}}
+gEmmcConfigGuid = {0xE0C6FB5D, 0x5696, 0x47F3, {0x84, 0xE8, 0xCC, 0x6C, 0x68, 0xA4, 0xB2, 0x1D}}
+gUfsConfigGuid = {0x3AF25C55, 0x76B4, 0x4367, {0x85, 0xEF, 0x9D, 0x51, 0x2F, 0x2F, 0x8F, 0xA7}}
+gEmmcDxeConfigGuid = {0x59440AA6, 0xEB45, 0x4E36, {0xBC, 0x90, 0xBE, 0xF9, 0x0C, 0xB0, 0xC8, 0x18}}
+gSerialIoConfigGuid  =  {0x6CC06EBF, 0x0D34, 0x4340, {0xBC, 0x16, 0xDA, 0x09, 0xE5, 0x78, 0x3A, 0xDB}}
+gSerialIrqConfigGuid  =  {0x251701E7, 0xE266, 0x4623, {0x99, 0x68, 0x73, 0x8C, 0xD2, 0x23, 0x10, 0x96}}
+gSpiConfigGuid  =  {0x150360EF, 0x99BE, 0x4E43, {0x94, 0xBB, 0xBD, 0x40, 0x26, 0xCA, 0x34, 0x57}}
+gEspiConfigGuid  =  {0x60FBF3B8, 0x96D4, 0x4187, {0x84, 0x9E, 0xAA, 0xF7, 0x5C, 0x4B, 0xE1, 0xE3}}
+gThermalConfigGuid  =  {0x4416506D, 0x1197, 0x4722, {0xA5, 0xB4, 0x46, 0x11, 0xF9, 0x23, 0x9E, 0xAE}}
+gUsbConfigGuid  =  {0xB2DA9CCD, 0x6A8C, 0x4BB6, {0xB3, 0xE6, 0xCD, 0xFB, 0xB7, 0x66, 0x8B, 0xDE}}
+gUsb2PhyConfigGuid  =  {0x576C1134, 0x2E0C, 0xCB7D, {0xCD, 0x3F, 0xAC, 0x68, 0x2D, 0xAE, 0xD3, 0xF2}}
+gUsb3HsioConfigGuid  =  {0xF8AFC238, 0xF176, 0x12CE, {0xBE, 0xF4, 0x69, 0xF9, 0xB1, 0xAC, 0x40, 0xD5}}
+gPchPcieStorageDetectHobGuid = {0xC682F3F4, 0x2F46, 0x495E, {0x98, 0xAA, 0x43, 0x14, 0x4B, 0xA5, 0xA4, 0x85}}
+gCnviConfigGuid = {0xE53EBEF7, 0x103D, 0x4A70, {0x9B, 0x6A, 0x73, 0xEE, 0x5F, 0x4C, 0x8D, 0xF5}}
+gHsioConfigGuid = {0xE53EBEE7, 0x103D, 0x4A71, {0x9B, 0x6A, 0x74, 0xEE, 0x5F, 0x4C, 0x8D, 0xF5}}
+gPchRstHobGuid =  {0x4ECA680C, 0x660D, 0x48F8, {0xAA, 0xD8, 0x94, 0xD6, 0x56, 0x10, 0xF9, 0x86}}
+gPchInfoHobGuid  =  {0x99FD5E18, 0xE262, 0x4E6A, {0x82, 0x66, 0x77, 0xD0, 0x36, 0x5F, 0xD6, 0x3E}}
+gGpioDxeConfigGuid  =  {0x06985984, 0xAFA3, 0x429C, {0x80, 0xCD, 0x69, 0x43, 0xF3, 0x38, 0x31, 0x4D}}
+gFivrConfigGuid  =  {0x68EE8BD4, 0x05F2, 0x4656, {0xAE, 0xE4, 0xAD, 0x10, 0xC7, 0x22, 0xC3, 0x4F}}
+gThcConfigGuid  =  {0x1B318AD1, 0xAA0D, 0x4764, {0x99, 0xFD, 0xBB, 0x2B, 0xF4, 0x7F, 0x7E, 0xD6}}
+gIehConfigGuid  =  {0x42C4D7F3, 0x981D, 0x4475, {0xA2, 0xAE, 0xAD, 0xCD, 0xD5, 0xCE, 0x87, 0x1E}}
+gRtcConfigGuid  =  {0x0E9259B8, 0x3DDE, 0x40C7, {0xAA, 0x5F, 0x94, 0x82, 0x9A, 0x86, 0x8F, 0xAF}}
+gCnviConfigGuid =  {0xa660970e, 0x511b, 0x46bb, {0xa7, 0xb8, 0xec, 0xdd, 0xf5, 0xe2, 0x2d, 0x73}}
+gGpioCheckConflictHobGuid = {0x5603f872, 0xefac, 0x40ae, {0xb9, 0x7e, 0x13, 0xb2, 0xf8, 0x07, 0x80, 0x21}}
+gPsfConfigGuid  =  {0x49B12CF6, 0x0A56, 0x4B9F, {0xA8, 0x4C, 0xF5, 0x7D, 0x21, 0x23, 0x8C, 0x77}}
+gHybridStorageConfigGuid = {0x265CE069, 0xD8CF, 0x48BE, {0xAE, 0x12, 0x02, 0x4C, 0x25, 0x12, 0xFA, 0xF8}}
+gHybridStorageHobGuid = {0xFF91F620, 0x069E, 0x4191, {0x83, 0x73, 0x11, 0x60, 0x9F, 0x24, 0x90, 0xEB}}
+gAdrConfigGuid = {0x5B36A07C, 0x3BBF, 0x4D53, {0x8A, 0x2D, 0xE1, 0xCF, 0x97, 0x39, 0x0C, 0x65}}
+gSpiConfigGuid = {0xD61A6A07, 0xAD25, 0xBFC2, {0x8C, 0x60, 0xD0, 0xD1, 0xF4, 0x13, 0x14, 0xBC}}
+
+##
+## Fusa
+##
+gFusaConfigGuid =  {0xF9225896, 0xA9C8, 0x4543, {0xBA, 0x9E, 0x53, 0x32, 0xD7, 0xBF, 0x8C, 0x2B}}
+gSiFusaInfoGuid = {0xcc7876ba, 0xee7b, 0x4bd4, {0x99, 0x4b, 0x7e, 0xc9, 0x74, 0xc9, 0xd8, 0x43}}
+
+##
+## SecurityPkg
+##
+## GUID used to "Tcg2PhysicalPresence" variable and "Tcg2PhysicalPresenceFlags" variable for TPM2 request and response.
+#  Include/Guid/Tcg2PhysicalPresenceData.h
+gEfiTcg2PhysicalPresenceGuid          = { 0xaeb9c5c1, 0x94f1, 0x4d02, { 0xbf, 0xd9, 0x46, 0x2, 0xdb, 0x2d, 0x3c, 0x54 }}
+gEfiTrEEPhysicalPresenceGuid          =  {0xf24643c2, 0xc622, 0x494e, {0x8a, 0x0d, 0x46, 0x32, 0x57, 0x9c, 0x2d, 0x5b}}
+gTcoWdtHobGuid                        = { 0x3e405418, 0x0d8c, 0x4f1a, { 0xb0, 0x55, 0xbe, 0xf9, 0x08, 0x41, 0x46, 0x8d }}
+
+##
+## UEFI Variable Support (Direct SPI and UFS)
+##
+gCseVariableStoragePpiInstanceGuid         = { 0x9513730d, 0x06ce, 0x4cf6, { 0x9d, 0x95, 0xb0, 0x76, 0x31, 0xbc, 0xd5, 0xa9}}
+gFvbVariableStoragePpiInstanceGuid         = { 0x5067b88a, 0xaa37, 0x414d, { 0xa3, 0xca, 0xc8, 0x37, 0xfc, 0xec, 0xd6, 0xf3}}
+gCseVariableStorageProtocolInstanceGuid    = { 0x5d5ede0b, 0x5d93, 0x4aae, { 0xa8, 0xec, 0x08, 0x41, 0xd0, 0x53, 0x85, 0xc4}}
+gFvbVariableStorageProtocolInstanceGuid    = { 0xe98252e8, 0xf209, 0x4ef5, { 0xab, 0x7e, 0x12, 0x69, 0x45, 0x14, 0x47, 0xbe}}
+gPeiVariableCacheHobGuid                   = { 0x35212b29, 0x128a, 0x4754, { 0xb9, 0x96, 0x62, 0x45, 0xcc, 0xa8, 0xa0, 0x66}}
+gCseVariableStorageSecurePreMemoryDataGuid = { 0xa1749e1e, 0x8ce1, 0x4310, { 0xbd, 0x3f, 0x64, 0xc9, 0x01, 0xc6, 0x13, 0xc2}}
+gCseVariableStorageGeneralDataAreaGuid     = { 0x6d7a6128, 0x685b, 0x4f75, { 0x87, 0x87, 0xba, 0x93, 0x08, 0x60, 0x75, 0x0c}}
+gCseVariableStorageFileSystemGuid          = { 0xdb798aca, 0x3533, 0x41c7, { 0x9a, 0x98, 0x00, 0x31, 0x1b, 0x66, 0x0a, 0x15}}
+gBugCheckVariableGuid                      = { 0xba57e015, 0x65b3, 0x4c3c, { 0xb2, 0x74, 0x65, 0x91, 0x92, 0xf6, 0x99, 0xe3}}
+
+##
+## PreMem Performance
+##
+gPerfPchPrePolicyGuid     = {0x3112356F, 0xCC77, 0x4E82, {0x86, 0xD5, 0x3E, 0x25, 0xEE, 0x81, 0x92, 0xA4}}
+gPerfSiValidateGuid       = {0x681F96E6, 0xF9CF, 0x464D, {0x97, 0x9A, 0xB1, 0x11, 0x33, 0xDE, 0x37, 0xA9}}
+gPerfPchValidateGuid      = {0xD0FF37D6, 0xA569, 0x4058, {0xB3, 0xDA, 0x29, 0x0B, 0x38, 0xC5, 0x32, 0x25}}
+gPerfAmtValidateGuid      = {0x9E949422, 0x4A7A, 0x4E41, {0xB0, 0xAB, 0x3C, 0x0D, 0x88, 0x0A, 0x00, 0xFF}}
+gPerfCpuValidateGuid      = {0xB760CFCC, 0xDEEF, 0x4C7E, {0x99, 0x5B, 0xED, 0xFE, 0xF2, 0x23, 0xB2, 0x09}}
+gPerfMeValidateGuid       = {0x8CF7A498, 0x588D, 0x4D39, {0xBD, 0xAC, 0x51, 0x0C, 0x31, 0xAF, 0x45, 0xD0}}
+gPerfSaValidateGuid       = {0xA73B382B, 0x62D4, 0x4A19, {0xBB, 0xF9, 0x09, 0x3E, 0xC5, 0xA5, 0x93, 0x11}}
+gPerfHeciPreMemGuid       = {0xD815D922, 0x4994, 0x40B3, {0x97, 0xCC, 0x07, 0xF3, 0x7D, 0x42, 0xE7, 0x97}}
+gPerfPchPreMemGuid        = {0xBB73E2B1, 0xB9FD, 0x4A80, {0xB8, 0x1A, 0x52, 0x39, 0xE9, 0x4D, 0x06, 0x2E}}
+gPerfCpuPreMemGuid        = {0xAC5FCBC6, 0x084D, 0x445D, {0xB3, 0xF3, 0xCA, 0x16, 0xDE, 0xE9, 0xBB, 0x47}}
+gPerfMePreMemGuid         = {0x6051338E, 0x0FFA, 0x40F7, {0xAF, 0xEF, 0xAB, 0x86, 0x7A, 0x38, 0xCC, 0xF3}}
+gPerfAmtPreMemGuid        = {0xDB732D50, 0x9BB8, 0x489A, {0xA1, 0xD1, 0xDD, 0xD2, 0x16, 0x1D, 0x72, 0xB8}}
+gPerfAmtPostMemGuid       = {0x0329D610, 0x4269, 0xD28F, {0x61, 0xBF, 0xB9, 0xA2, 0xD9, 0xFA, 0x96, 0x93}}
+gPerfSaPreMemGuid         = {0x76F18BDA, 0x2195, 0x4FB6, {0x9A, 0x94, 0x0E, 0x0B, 0xAC, 0xDE, 0xEC, 0xAB}}
+gPerfEvlGuid              = {0x8221518B, 0xAC19, 0x4E32, {0xAB, 0x5F, 0x00, 0x47, 0x0A, 0x50, 0x69, 0x40}}
+gPerfMemGuid              = {0x2B57B316, 0x5CF7, 0x4847, {0xB0, 0x76, 0x6B, 0x5D, 0x23, 0xC3, 0xAA, 0x3E}}
+
+##
+## PostMem Performance
+##
+gPerfPchPostMemGuid       = {0x70B67A99, 0x5556, 0x4315, {0xB3, 0x05, 0xD5, 0xDC, 0x4A, 0x35, 0x63, 0x70}}
+gPerfSaPostMemGuid        = {0x9FF0CE92, 0x883F, 0x43DC, {0x8A, 0x07, 0xE0, 0xCB, 0x6D, 0x56, 0x7D, 0xE0}}
+gPerfS3CpuInitPostMemGuid = {0x976262C2, 0xD202, 0x4D12, {0x82, 0xAD, 0xF4, 0xA9, 0x8F, 0x9B, 0x96, 0x01}}
+gPerfSaSecLockPostMemGuid = {0x272AC110, 0x0B60, 0x4D07, {0xA5, 0x58, 0x6D, 0x73, 0xE2, 0x43, 0x85, 0x95}}
+gPerfCpuStrapPostMemGuid  = {0x8EF4372B, 0x68F0, 0x4957, {0xBC, 0x4D, 0x7E, 0x5C, 0xFE, 0xDA, 0xB6, 0x3E}}
+gPerfMpPostMemGuid        = {0xA59BAC5B, 0xC6A4, 0x4AEB, {0x84, 0x32, 0x7A, 0x8B, 0x6B, 0x68, 0x5F, 0x37}}
+gPerfCpuPostMemGuid       = {0xE2FE5ED3, 0x1417, 0x451A, {0x95, 0xC9, 0xD0, 0xB2, 0xB9, 0x7B, 0xE0, 0x54}}
+gPerfSaResetPostMemGuid   = {0xBE152BEE, 0xFD19, 0x4274, {0xA8, 0xBA, 0xFB, 0x31, 0x42, 0xB5, 0xB5, 0xC3}}
+gPerfCpuPowerMgmtGuid     = {0x9ED307D6, 0x4AEB, 0x44A9, {0x9B, 0x11, 0xD8, 0x21, 0x84, 0x9A, 0xCB, 0xF7}}
+gPerfMePostMemGuid        = {0x2CC8626D, 0x3387, 0x4817, {0xAB, 0xF6, 0x86, 0x9A, 0xF5, 0xF0, 0x51, 0xAA}}
+gPerfHdaPostMemGuid       = {0xB31883B7, 0x5A05, 0x4040, {0x40, 0x80, 0x66, 0x8D, 0x29, 0x13, 0xD7, 0x84}}
+
+##
+## Dp-In Guid
+##
+## Include/DpInDataHob.h
+gDpInHobGuid = {0x3e110a83, 0xb94b, 0x4648, {0xa2, 0x26, 0x50, 0x9b, 0xd5, 0x55, 0xe3, 0x6b}}
+## Include/ConfigBlock/Tcss/DpInPreMemConfig.h
+gDpInPreMemConfigGuid = {0x80c14ba, 0xcc84, 0x4746, {0xbf, 0x6b, 0xd1, 0xf1, 0x8e, 0xaa, 0xe8, 0x35}}
+
+[Protocols.common.Private]
+##
+## SA
+##
+gSaIotrapSmiProtocolGuid    = { 0x1861e089, 0xcaa3, 0x473e, { 0x84, 0x32, 0xdc, 0x1f, 0x94, 0xc6, 0xc1, 0xa6 }}
+gCpuPcieIoTrapProtocolGuid  = { 0xda904080, 0x33ab, 0x48ca, { 0x97, 0x5b, 0x5f, 0x2f, 0x23, 0x8a, 0x41, 0xb4 }}
+
+gPchPcieIoTrapProtocolGuid      = { 0xd66a1cf,  0x79ad, 0x494b, { 0x97, 0x8b, 0xb2, 0x59, 0x81, 0x68, 0x93, 0x34 }}
+
+[Protocols]
+##
+## MdeModulePkg
+##
+gEfiSmmVariableProtocolGuid  =  {0xed32d533, 0x99e6, 0x4209, {0x9c, 0xc0, 0x2d, 0x72, 0xcd, 0xd9, 0x98, 0xa7}}
+gEdkiiPlatformSpecificResetFilterProtocolGuid  = { 0x695d7835, 0x8d47, 0x4c11, { 0xab, 0x22, 0xfa, 0x8a, 0xcc, 0xe7, 0xae, 0x7a } }
+gEdkiiPlatformSpecificResetHandlerProtocolGuid = { 0x2df6ba0b, 0x7092, 0x440d, { 0xbd, 0x4, 0xfb, 0x9, 0x1e, 0xc3, 0xf3, 0xc1 } }
+
+##
+## SystemAgent
+##
+gBdatAccessGuid                 =  {0x9477482c, 0x8717, 0x4725, {0x98, 0x28, 0x7b, 0xd8, 0xc9, 0xa3, 0x75, 0x6a}}
+gIgdOpRegionProtocolGuid        =  {0x9e67aecf, 0x4fbb, 0x4c84, {0x99, 0xa5, 0x10, 0x73, 0x40, 0x7,  0x6d, 0xb4}}
+gMemInfoProtocolGuid            =  {0xd4d2f201, 0x50e8, 0x4d45, {0x8e, 0x5,  0xfd, 0x49, 0xa8, 0x2a, 0x15, 0x69}}
+gSaPolicyProtocolGuid           =  {0xc6aa1f27, 0x5597, 0x4802, {0x9f, 0x63, 0xd6, 0x28, 0x36, 0x59, 0x86, 0x35}}
+gSaNvsAreaProtocolGuid          =  {0x149a10a5, 0x9d06, 0x4c6b, {0xbe, 0x44, 0x08, 0x92, 0xce, 0x20, 0x61, 0xac}}
+gGopPolicyProtocolGuid          =  {0xec2e931b, 0x3281, 0x48a5, {0x81, 0x07, 0xdf, 0x8a, 0x8b, 0xed, 0x3c, 0x5d}}
+gGen12PolicyProtocolGuid        =  {0x40f60ea0, 0x6c96, 0x4ed3, {0x96, 0xe5, 0xba, 0x6f, 0x6d, 0x66, 0x28, 0x9f}}
+gGen9PolicyProtocolGuid         =  {0xeaaed1ba, 0xf15c, 0x4112, {0xb5, 0x82, 0x90, 0x63, 0xac, 0xa0, 0x7f, 0x06}}
+gGopComponentName2ProtocolGuid  =  {0x651b7ebd, 0xce13, 0x41d0, {0x82, 0xe5, 0xa0, 0x63, 0xab, 0xbe, 0x9b, 0xb6}}
+gGopOverrideProtocolGuid        =  {0x4a89a16e, 0x67b8, 0x4429, {0x8c, 0x47, 0x43, 0x67, 0x90, 0xf2, 0xf2, 0x69}}
+gMemoryAddressEncodeDecodeProtocolGuid = {0x603df7ca, 0x1ba8, 0x4c12, {0xa9, 0x8a, 0x49, 0x6d, 0xfe, 0x77, 0xeb, 0xdf}}
+
+##
+## TBT
+##
+gITbtPolicyProtocolGuid       =  {0xb0563c42, 0x28ea, 0x40e6, {0x99, 0x84, 0xd5, 0xbf, 0xf8, 0xb0, 0x40, 0x56}}
+gITbtNvsAreaProtocolGuid      =  {0xdabf85bd, 0xfbdc, 0x4ed2, {0xb1, 0x0d, 0xc9, 0x08, 0xd0, 0x8c, 0xee, 0xe8}}
+gDisableITbtBmeProtocolGuid      =  {0x89a9adc3, 0x9b7c, 0x4b53, {0x82, 0xbf, 0x78, 0x72, 0x6b, 0x91, 0x4f, 0x9f}}
+
+##
+## Cpu
+##
+gCpuInfoProtocolGuid  =  {0xe223cf65, 0xf6ce, 0x4122, {0xb3, 0xaf, 0x4b, 0xd1, 0x8a, 0xff, 0x40, 0xa1}}
+gSmmBiosGuardProtocolGuid  =  {0x17565311, 0x4b71, 0x4340, {0x88, 0xaa, 0xdc, 0x9f, 0x44, 0x22, 0xe5, 0x3a}}
+gCpuNvsAreaProtocolGuid  =  {0xb9cf3f43, 0xbe3e, 0x4e45, {0xa0, 0xbe, 0x1a, 0x4, 0x89, 0xdf, 0x1a, 0xc9}}
+gDxeCpuPolicyProtocolGuid  =  {0x8282b977, 0x22f9, 0x4134, {0x99, 0x43, 0x7b, 0xcc, 0x5f, 0x40, 0x33, 0x52}}
+gBiosGuardNvsAreaProtocolGuid  =  {0x5df588da, 0x991e, 0x4a7f, {0x80, 0x51, 0x70, 0xc7, 0x12, 0xb7, 0xba, 0xb0}}
+gSmmResourceConfigProtocolGuid = {0xA37FC2D2, 0x822D, 0x4A63, {0x9C, 0x42, 0xBE, 0xB1, 0xD6, 0xEE, 0x85, 0x39}}
+
+##
+## Me
+##
+gActiveManagementProtocolGuid     = {0xd25dc167, 0xeb6a, 0x432d, {0x65, 0x91, 0xbf, 0x80, 0x29, 0xb0, 0x05, 0xbb}}
+gAlertStandardFormatProtocolGuid  = {0x45de9920, 0xcd54, 0x446a, {0xa0, 0x3c, 0x22, 0xe6, 0xfb, 0xb4, 0x51, 0xe4}}
+gHeciProtocolGuid                 = {0x3c7bc880, 0x41f8, 0x4869, {0xae, 0xfc, 0x87, 0x0a, 0x3e, 0xd2, 0x82, 0x99}}
+gHeciFlowProtocolGuid             = {0x1498d127, 0x123c, 0x4e52, {0x84, 0x00, 0xcc, 0x3c, 0x9f, 0x79, 0xc4, 0x0e}}
+gMebxProtocolGuid                 = {0x01ab1829, 0xcecd, 0x4cfa, {0xa1, 0x8c, 0xea, 0x75, 0xd6, 0x6f, 0x3e, 0x74}}
+gDxeMePolicyGuid                  = {0xa0b5dc52, 0x4f34, 0x3990, {0xd4, 0x91, 0x10, 0x8b, 0xe8, 0xba, 0x75, 0x42}}
+gMeInfoProtocolGuid               = {0x7523c8e4, 0x4fbe, 0x9661, {0x29, 0x96, 0x14, 0x97, 0xff, 0x36, 0x2f, 0x3b}}
+gPlatformMeHookProtocolGuid       = {0xbc52476e, 0xf67e, 0x4301, {0xb2, 0x62, 0x36, 0x9c, 0x48, 0x78, 0xaa, 0xc2}}
+gMeNvsAreaProtocolGuid            = {0x3bffecfd, 0xd75f, 0x4975, {0xb8, 0x88, 0x39, 0x02, 0xbd, 0x69, 0x00, 0x2b}}
+gJhiProtocolGuid                  = {0xccba3051, 0xa574, 0x4f9d, {0x96, 0xf4, 0xec, 0x0d, 0x4a, 0x87, 0xbc, 0x5a}}
+gIntegratedTouchHidProtocolGuid   = {0x3d0479c1, 0x6b19, 0x4191, {0xb8, 0x09, 0x60, 0x08, 0xdd, 0x07, 0x97, 0x55}}
+gIntegratedTouchProtocolGuid      = {0x2b12e46f, 0x3c24, 0x47ff, {0x8b, 0x89, 0xc0, 0x60, 0x2c, 0x1c, 0x61, 0x42}}
+gMeEopDoneProtocolGuid            = {0x8d9b3387, 0x73db, 0x456f, {0x88, 0x9d, 0x6f, 0xfe, 0x90, 0x82, 0x64, 0x09}}
+gMeSendEopInFspProtocolGuid       = {0xcecdba92, 0x76c6, 0x4063, {0xaa, 0x6b, 0x19, 0xfc, 0x60, 0x5c, 0x70, 0xff}}
+
+gHeciAccessProtocolGuid          = {0x3a5aab32, 0xd5a7, 0x4ce8, {0x88, 0xe2, 0xed, 0x8f, 0x7b, 0x43, 0x23, 0x9d}}
+gHeciTransportProtocolGuid       = {0x9fc932b9, 0x8851, 0x43f7, {0x8a, 0x58, 0xa8, 0xd9, 0x04, 0x01, 0xcd, 0x78}}
+gHeciControlProtocolGuid         = {0xd86381d8, 0xff7e, 0x462e, {0x9b, 0x55, 0x02, 0x0a, 0x64, 0x1b, 0xe3, 0x4f}}
+gHeciAccessSmmProtocolGuid       = {0x5da6182c, 0xf679, 0x49eb, {0x96, 0xf5, 0xe6, 0x24, 0x9b, 0x54, 0x0b, 0x96}}
+gHeciTransportSmmProtocolGuid    = {0xf5f7b292, 0xbb38, 0x4e59, {0xa1, 0x6e, 0x0f, 0x27, 0x15, 0xd4, 0xb7, 0xf4}}
+gHeciControlSmmProtocolGuid      = {0x7e1e508d, 0x7def, 0x4d69, {0xa9, 0xb3, 0xa5, 0x23, 0xe8, 0x48, 0xc6, 0x98}}
+
+##
+## Amt
+##
+gAmtSaveMebxProtocolGuid          = {0x86682c04, 0xea42, 0x49e5, {0x96, 0x81, 0xe3, 0x32, 0xaa, 0xb0, 0x9e, 0xd7}}
+gDxeAmtPolicyGuid                 = {0x6725e645, 0x4a7f, 0x9969, {0x82, 0xec, 0xd1, 0x87, 0x21, 0xde, 0x5a, 0x57}}
+gAmtReadyToBootProtocolGuid       = {0xcc9d5c0b, 0x9010, 0x45f1, {0x99, 0x3c, 0x83, 0x27, 0x67, 0xf1, 0x67, 0x77}}
+gMeSmbiosTablesUpdateProtocolGuid = {0x5054ee06, 0x4ce0, 0x4acc, {0x9a, 0x80, 0xdf, 0x73, 0xbf, 0xa5, 0x38, 0xdd}}
+gOneClickRecoveryProtocolGuid     = {0x93598eac, 0xc62b, 0x4dbb, {0x96, 0x76, 0xe0, 0x5e, 0x8c, 0xc3, 0x84, 0x44}}
+
+##
+## PCH
+##
+gThcProtocolGuid  = {0x00860921, 0x7B9B, 0x4EA8, {0xAD, 0x23, 0x3C, 0xCA, 0x33, 0x9E, 0x7D, 0xFE}}
+gPchSpiProtocolGuid  =  {0xc7d289, 0x1347, 0x4de0, {0xbf, 0x42, 0xe, 0x26, 0x9d, 0xe, 0xf3, 0x4a}}
+gWdtProtocolGuid  =  {0xb42b8d12, 0x2acb, 0x499a, {0xa9, 0x20, 0xdd, 0x5b, 0xe6, 0xcf, 0x09, 0xb1}}
+gPchSerialIoUartDebugInfoProtocolGuid  =  {0x2fd2b1bd, 0x0387, 0x4ec6, {0x94, 0x1f, 0xf1, 0x4b, 0x7f, 0x1c, 0x94, 0xb6}}
+gEfiSmmSmbusProtocolGuid  =  {0x72e40094, 0x2ee1, 0x497a, {0x8f, 0x33, 0x4c, 0x93, 0x4a, 0x9e, 0x9c, 0x0c}}
+gPchSmmSpiProtocolGuid  =  {0x56521f06, 0xa62, 0x4822, {0x99, 0x63, 0xdf, 0x1, 0x9d, 0x72, 0xc7, 0xe1}}
+gPchSmmIoTrapControlGuid  =  {0x514d2afd, 0x2096, 0x4283, {0x9d, 0xa6, 0x70, 0x0c, 0xd2, 0x7d, 0xc7, 0xa5}}
+gPchTcoSmiDispatchProtocolGuid  =  {0x9e71d609, 0x6d24, 0x47fd, {0xb5, 0x72, 0x61, 0x40, 0xf8, 0xd9, 0xc2, 0xa4}}
+gPchPcieSmiDispatchProtocolGuid  =  {0x3e7d2b56, 0x3f47, 0x42aa, {0x8f, 0x6b, 0x22, 0xf5, 0x19, 0x81, 0x8d, 0xab}}
+gPchAcpiSmiDispatchProtocolGuid  =  {0xd52bb262, 0xf022, 0x49ec, {0x86, 0xd2, 0x7a, 0x29, 0x3a, 0x7a, 0x05, 0x4b}}
+gPchSmiDispatchProtocolGuid  =  {0xE6A81BBF, 0x873D, 0x47FD, {0xB6, 0xBE, 0x61, 0xB3, 0xE5, 0x72, 0x09, 0x93}}
+gPchNvsAreaProtocolGuid  =  {0x2e058b2b, 0xedc1, 0x4431, {0x87, 0xd9, 0xc6, 0xc4, 0xea, 0x10, 0x2b, 0xe3}}
+gPchEspiSmiDispatchProtocolGuid  =  {0xB3C14FF3, 0xBAE8, 0x456C, {0x86, 0x31, 0x27, 0xFE, 0x0C, 0xEB, 0x34, 0x0C}}
+gPchSmmPeriodicTimerControlGuid  =  {0x6906E93B, 0x603B, 0x4A0F, {0x86, 0x92, 0x83, 0x20, 0x04, 0xAA, 0xF2, 0xDB}}
+gIoTrapExDispatchProtocolGuid  =  {0x5B48E913, 0x707B, 0x4F9D, {0xAF, 0x2E, 0xEE, 0x03, 0x5B, 0xCE, 0x39, 0x5D}}
+gPchPolicyProtocolGuid           =  {0x543d5c93, 0x6a28, 0x4513, {0x85, 0x9a, 0x82, 0xa7, 0xb9, 0x12, 0xcb, 0xbe}}
+gScsEmmcSoftwareTuningProtocolGuid = {0x972215b2, 0x9616, 0x4de4, {0xa9, 0x75, 0xb0, 0x74, 0x3e, 0xe1, 0x78, 0x54}}
+
+##
+## Hsti
+##
+## HstiSiliconDxe Driver Entry Point
+gHstiProtocolGuid = { 0x1b05de41, 0xc93b, 0x4bb4, { 0xad, 0x47, 0x2a, 0x78, 0xac, 0xf, 0xc9, 0xe4 }}
+## Handler to gather and publish HSTI results on ReadyToBootEvent
+gHstiPublishCompleteProtocolGuid =  {0x0f500be6, 0xece4, 0x4ed8, { 0x90, 0x81, 0x9a, 0xa9, 0xa5, 0x23, 0xfb, 0x7b}}
+gEfiAdapterInformationProtocolGuid = { 0xE5DD1403, 0xD622, 0xC24E, {0x84, 0x88, 0xC7, 0x1B, 0x17, 0xF5, 0xE8, 0x02 }}
+
+##
+## Silicon Policy
+##
+## Include/Protocol/SiPolicyProtocol.h
+gDxeSiPolicyProtocolGuid = { 0xeca27516, 0x306c, 0x4e28, { 0x8c, 0x94, 0x4e, 0x52, 0x10, 0x96, 0x69, 0x5e }}
+
+##
+## DGR
+##
+gEfiSpaLogOutputProtocolGuid = { 0x1d10d46b, 0x0306, 0x454a, { 0x90, 0x8c, 0x93, 0x65, 0xb3, 0x8a, 0x90, 0x26 }}
+
+[Ppis.common.Private]
+gPchHsioChipsetInitSusTblDataPpiGuid = { 0x97ed4e5d, 0x01a5, 0x4a3c, { 0xb7, 0xe9, 0x1a, 0x4e, 0xa3, 0xdd, 0x23, 0xce }}
+gHybridStorageCfgPpiGuid = {0x8557e481, 0xc00e, 0x4929, {0xb4, 0x53, 0xf6, 0xc2, 0x53, 0x79, 0xb0, 0x13}}
+
+[Ppis]
+##
+## MdeModulePkg
+##
+gPeiCapsulePpiGuid  =  {0x3acf33ee, 0xd892, 0x40f4, {0xa2, 0xfc, 0x38, 0x54, 0xd2, 0xe1, 0x32, 0x3d}}
+gPeiSmmControlPpiGuid  =  {0x61c68702, 0x4d7e, 0x4f43, {0x8d, 0xef, 0xa7, 0x43, 0x05, 0xce, 0x74, 0xc5}}
+gEdkiiPlatformSpecificResetFilterPpiGuid = { 0x8c9f4de3, 0x7b90, 0x47ef, { 0x93, 0x8, 0x28, 0x7c, 0xec, 0xd6, 0x6d, 0xe8 } }
+gEdkiiPlatformSpecificResetNotificationPpiGuid = { 0xe09f355d, 0xdae8, 0x4910, { 0xb1, 0x4a, 0x92, 0x78, 0xf, 0xdc, 0xf7, 0xcb } }
+gEdkiiPlatformSpecificResetHandlerPpiGuid = { 0x75cf14ae, 0x3441, 0x49dc, { 0xaa, 0x10, 0xbb, 0x35, 0xa7, 0xba, 0x8b, 0xab } }
+
+##
+## SecurityPkg
+##
+gPeiTpmInitializedPpiGuid  =  {0xe9db0d58, 0xd48d, 0x47f6, {0x9c, 0x6e, 0x6f, 0x40, 0xe8, 0x6c, 0x7b, 0x41}}
+gPeiTpmInitializationDonePpiGuid = {0xa030d115, 0x54dd, 0x447b, { 0x90, 0x64, 0xf2, 0x6, 0x88, 0x3d, 0x7c, 0xcc}}
+##
+## Common
+##
+## Include/Ppi/SiPolicy.h
+gSiPolicyPpiGuid  =  {0xaebffa01, 0x7edc, 0x49ff, {0x8d, 0x88, 0xcb, 0x84, 0x8c, 0x5e, 0x86, 0x70}}
+## Include/Ppi/SiPolicy.h
+gSiPreMemPolicyPpiGuid = {0xc133fe57, 0x17c7, 0x4b09, {0x8b, 0x3c, 0x97, 0xc1, 0x89, 0xd0, 0xab, 0x8d}}
+gFspApiModePpiGuid          = {0xa1eeab87, 0xc859, 0x479d, {0x89, 0xb5, 0x14, 0x61, 0xf4, 0x06, 0x1a, 0x3e}}
+## Silicon Initialization PPI is used to export End of Silicon init.
+gEndOfSiInitPpiGuid         = {0xE2E3D5D1, 0x8356, 0x4F96, {0x9C, 0x9E, 0x2E, 0xC3, 0x48, 0x1D, 0xEA, 0x88}}
+gEfiEndOfPeiSignal2PpiGuid  = {0x22918381, 0xd018, 0x4d7c, {0x9d, 0x62, 0xf5, 0xa5, 0x70, 0x1c, 0x66, 0x80}}
+gFspTempRamExitPpiGuid      = {0xbc1cfbdb, 0x7e50, 0x42be, {0xb4, 0x87, 0x22, 0xe0, 0xa9, 0x0c, 0xb0, 0x52}}
+gFspmArchConfigPpiGuid      = {0x824d5a3a, 0xaf92, 0x4c0c, {0x9f, 0x19, 0x19, 0x52, 0x6d, 0xca, 0x4a, 0xbb}}
+gSiPreMemDefaultPolicyInitPpiGuid =  {0xfec36242, 0xf8d8, 0x4b43, {0x87, 0x94, 0x4f, 0x1f, 0x9f, 0x63, 0x8d, 0xdc}}
+gSiPreMemPolicyReadyPpiGuid = {0x85270bef, 0x6984, 0x4375, {0xa6, 0xea, 0xb5, 0xaa, 0x90, 0x6e, 0xdd, 0x4a}}
+gSiDefaultPolicyInitPpiGuid = {0xf69abf86, 0x4048, 0x44ef, { 0xa8, 0xef, 0x6c, 0x7f, 0x20, 0x4a, 0xc8, 0xda}}
+gSiPolicyReadyPpiGuid       = {0xd570de8c, 0xb9c4, 0x4ffa, {0xad, 0xee, 0xa5, 0x82, 0x7c, 0xe3, 0x17, 0x79}}
+
+##
+## UEFI Variable Support (Override Until BP1.5)
+##
+gEdkiiVariableStoragePpiGuid  =  { 0x90d915c5, 0xe4c1, 0x4da8, {0xa7, 0x6f, 0x9,  0xe5, 0x78, 0x91, 0x65, 0x48}}
+gEdkiiVariableStorageSelectorPpiGuid  =  { 0x782546d1, 0x03ab, 0x41e4, {0xa0, 0x1d, 0x7a, 0x9b, 0x22, 0xba, 0x2e, 0x1e}}
+gReadOnlyVariablePreMemoryDescriptorPpiGuid  =  { 0xbe136fc9, 0xc277, 0x4dd1, {0xbe, 0x42, 0xce, 0xf0, 0x9f, 0xf4, 0x3f, 0x55}}
+gEfiReadyToInstallEndOfPei2PpiGuid = {0xeef72924, 0x2db2, 0x4569, { 0x86, 0x3f, 0xd4, 0x86, 0xae, 0x7a, 0xe4, 0x12}}
+
+##
+## SystemAgent
+##
+gSsaBiosCallBacksPpiGuid  =  {0x99b56126, 0xe16c, 0x4d9b, {0xbb, 0x71, 0xaa, 0x35, 0x46, 0x1a, 0x70, 0x2f}}
+gSsaBiosServicesPpiGuid   =  {0x55750d10, 0x6d3d, 0x4bf5, {0x89, 0xd8, 0xe3, 0x5e, 0xf0, 0xb0, 0x90, 0xf4}}
+gEnablePeiGraphicsPpiGuid =  {0x8e3bb474, 0x545,  0x4902, {0x86, 0xb0, 0x6c, 0xb5, 0xe2, 0x64, 0xb4, 0xa5}}
+gPeiGraphicsFramebufferReadyPpiGuid = {0x590ad868, 0xb0b1, 0x4d20, {0x91, 0xff, 0xc2, 0xa9, 0xd6, 0x88, 0x81, 0x94}}
+gMrcMemoryInitDonePpiGuid =  {0x0ff07255, 0x67c2, 0x456d, {0x9a, 0x95, 0xc9, 0x16, 0x2c, 0x23, 0x86, 0x8d}}
+## X Compatibility support PPI
+gCompatibleMemoryInitPpiGuid = {0xca311f82, 0xf490, 0x4b12, {0x9e, 0xe1, 0x2b, 0x66, 0xa3, 0x6c, 0x3e, 0xa}}
+gVmdInitDonePpiGuid =          {0x42a187c8, 0xca0a, 0x4750, {0x82, 0xfd, 0xc9, 0xa0, 0xd5, 0x9, 0xfe, 0xd1}}
+
+##
+## TwoLm
+##
+gMrcMemoryInitDonePpiGuid  = { 0x598907f5, 0xd5fc, 0x435c, { 0x8a, 0x7f, 0x53, 0xc5, 0xa4, 0xb5, 0x31, 0xc4}}
+
+##
+## Nvdimm Cache Info
+##
+gNvdimmCachePpiGuid  = { 0x1bbc5601, 0xe571, 0x4ae0, { 0xbc, 0x38, 0xb8, 0x65, 0x0d, 0x50, 0x6f, 0x5b}}
+
+##
+## Cpu
+##
+gPeiCachePpiGuid  =  {0x09be4bc2, 0x790e, 0x4dea, {0x8b, 0xdc, 0x38, 0x05, 0x16, 0x98, 0x39, 0x44}}
+gPeiTxtMemoryUnlockedPpiGuid  =  {0x38cdd10b, 0x767d, 0x4f6e, {0xa7, 0x44, 0x67, 0xee, 0x1d, 0xfe, 0x2f, 0xa5}}
+gPeiTxtReadyToRunMemoryInitPpiGuid = {0x9ecafd30, 0x29e2, 0x42f6, {0xba, 0xf3, 0x8b, 0x7d, 0xb8, 0xfe, 0x1f, 0x22}}
+gPeiReadyToInstallMpPpiGuid = { 0x1a266768, 0xfd43, 0x4e18, { 0xa8, 0x8a, 0x35, 0xc7, 0x94, 0xc3, 0x91, 0x0e }}
+##
+## Me
+##
+gHeciPpiGuid  =  {0xd14319e2, 0x407a, 0x9580, {0x8d, 0xe5, 0x51, 0xa8, 0xff, 0xc6, 0xd7, 0xd7}}
+gMbpSensitivePpiGuid  =  {0xed7c9ce9, 0x5912, 0x4807, {0xec, 0x90, 0x22, 0x18, 0xbc, 0x7b, 0xfc, 0x6c}}
+gHeci3IntegratedTouchControllerGuid  =  {0x3e8d0870, 0x271a, 0x4208, {0x8e, 0xb5, 0x9a, 0xcb, 0x94, 0x02, 0xae, 0x04}}
+gSiNvmOwnershipAcquiredPpiGuid = {0xe5db3d8c, 0xefa4, 0x4308, {0x9a, 0xab, 0x6b, 0x97, 0x81, 0x09, 0x98, 0xa0}}
+gHeciAccessPpiGuid = {0x3a5aab32, 0xd5a7, 0x4ce8, {0x88, 0xe2, 0xed, 0x8f, 0x7b, 0x43, 0x23, 0x9d}}
+gHeciTransportPpiGuid = {0x9fc932b9, 0x8851, 0x43f7, {0x8a, 0x58, 0xa8, 0xd9, 0x04, 0x01, 0xcd, 0x78}}
+gHeciControlPpiGuid  = {0xd86381d8, 0xff7e, 0x462e, {0x9b, 0x55, 0x02, 0x0a, 0x64, 0x1b, 0xe3, 0x4f}}
+gMeBeforeDidSentPpiGuid = {0xd497b143, 0xf3ef, 0x4192, {0xa8, 0xc5, 0x5e, 0xf6, 0xcd, 0x6e, 0x4c, 0x87}}
+
+##
+## PCH
+##
+gWdtPpiGuid  =  {0xf38d1338, 0xaf7a, 0x4fb6, {0x91, 0xdb, 0x1a, 0x9c, 0x21, 0x83, 0x57, 0x0d}}
+gPchSpiPpiGuid  =  {0xdade7ce3, 0x6971, 0x4b75, {0x82, 0x5e, 0xe, 0xe0, 0xeb, 0x17, 0x72, 0x2d}}
+gPeiSmbusPolicyPpiGuid  =  {0x63b6e435, 0x32bc, 0x49c6, {0x81, 0xbd, 0xb7, 0xa1, 0xa0, 0xfe, 0x1a, 0x6c}}
+
+##
+## TCSS
+##
+gTcssPeiInitDonePpiGuid = {0x5ad291b8, 0xace4, 0x416a, {0xb7, 0x50, 0x7, 0x63, 0x59, 0xfc, 0xc1, 0x5b}}
+
+[LibraryClasses]
+## @libraryclass
+## Common
+##
+MmPciLib|Include/Library/MmPciLib.h
+
+## @libraryclass
+## SampleCode
+##
+## CPU
+##
+CpuPolicyLib|Cpu/Include/Library/CpuPolicyLib.h
+
+## @libraryclass
+## Me
+##
+
+MeChipsetLib|Me/Include/Library/MeChipsetLib.h
+
+PeiMePolicyLib|Me/Include/Library/PeiMePolicyLib.h
+PttHciLib|Me/Include/Library/PttHciLib.h
+PttHeciLib|Me/Include/Library/PttHeciLib.h
+## @libraryclass
+## Pch
+##
+GpioLib|Include/Library/GpioLib.h
+GpioLib|Include/Library/GpioNativeLib.h
+PchCycleDecodingLib|Pch/Include/Library/PchCycleDecodingLib.h
+EspiLib|Include/Library/PchEspiLib.h
+GbeLib|Include/Library/GbeLib.h
+GbeMdiLib|IpBlock/Gbe/IncludePrivate/Library/GbeMdiLib.h
+PchHsioLib|Pch/IncludePrivate/PchHsio.h
+PchInfoLib|Pch/Include/Library/PchInfoLib.h
+PchP2sbLib|Pch/Include/Library/PchP2sbLib.h
+PchPcieRpLib|Pch/Include/Library/PchPcieRpLib.h
+PchPcrLib|Pch/Include/Library/PchPcrLib.h
+PchPolicyLib|Pch/Include/Library/PchPolicyLib.h
+PchSbiAccessLib|Pch/IncludePrivate/Library/PchSbiAccessLib.h
+SerialIoAccessLib|Include/Library/SerialIoAccessLib.h
+DxePchPolicyLib|Pch/Include/Library/DxePchPolicyLib.h
+
+## @libraryclass
+## Sa
+##
+DxeSaPolicyLib|SystemAgent/Include/Library/DxeSaPolicyLib.h
+SaPlatformLib|SystemAgent/Include/Library/SaPlatformLib.h
+Include/Library/VoltageRegulatorCommands.h
+
+[PcdsFixedAtBuild]
+## From MdeModulePkg.dec
+## Progress Code for S3 Suspend start.
+## PROGRESS_CODE_S3_SUSPEND_START   = (EFI_SOFTWARE_SMM_DRIVER | (EFI_OEM_SPECIFIC | 0x00000000))    = 0x03078000
+gSiPkgTokenSpaceGuid.PcdProgressCodeS3SuspendStart|0x03078000|UINT32|0x30001032
+## Progress Code for S3 Suspend end.
+## PROGRESS_CODE_S3_SUSPEND_END   = (EFI_SOFTWARE_SMM_DRIVER | (EFI_OEM_SPECIFIC | 0x00000001))    = 0x03078001
+gSiPkgTokenSpaceGuid.PcdProgressCodeS3SuspendEnd|0x03078001|UINT32|0x30001033
+##
+## PcdNemCodeCacheBase is usally the same as PEI FV Base address,
+## FLASH_BASE+FLASH_REGION_FV_RECOVERY_OFFSET from PlatformPkg.fdf.
+##
+## Restriction:
+## 1) PcdNemCodeCacheBase - (PcdTemporaryRamBase + PcdTemporaryRamSize) >= 4K
+## 2) PcdTemporaryRamBase >= 4G - 64M
+##
+gSiPkgTokenSpaceGuid.PcdNemCodeCacheBase|0xFFF80000|UINT32|0x20000009
+##
+## NemCodeCacheSize is usally the same as PEI FV Size,
+## FLASH_REGION_FV_RECOVERY_SIZE from PlatformPkg.fdf.
+##
+## Restriction:
+## 1) PcdNemTotalCacheSize = NemCodeCacheSize + PcdTemporaryRamSize
+## <= Maximun CPU NEM total size (Code + Data)
+## = LLC size - 0.5M
+## 2) PcdTemporaryRamSize  <= Maximum CPU NEM data size
+## =  MLC size
+## NOTE: The size restriction may be changed in next generation processor.
+## Please refer to Processor BWG for detail.
+##
+gSiPkgTokenSpaceGuid.PcdBiosAreaBaseAddress|0xFF800000|UINT32|0x10000001
+gSiPkgTokenSpaceGuid.PcdBiosSize|0x00800000|UINT32|0x10000002
+gSiPkgTokenSpaceGuid.PcdTemporaryRamBase|0xfef00000|UINT32|0x00010028
+gSiPkgTokenSpaceGuid.PcdTemporaryRamSize|0x2000|UINT32|0x00010029
+gSiPkgTokenSpaceGuid.PcdTopMemoryCacheSize|0x0|UINT32|0x0001002A
+gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase|0xFFE60000|UINT32|0x30000004
+gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize|0x000A0000|UINT32|0x30000005
+gSiPkgTokenSpaceGuid.PcdFlashMicrocodeOffset|0x00000060|UINT32|0x30000013
+gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvOffset|0x00660000|UINT32|0x30000006
+##
+## The CPU Trace Hub's BARs base and size
+##
+gSiPkgTokenSpaceGuid.PcdCpuTraceHubMtbBarBase|0xfad00000|UINT32|0x30000007
+gSiPkgTokenSpaceGuid.PcdCpuTraceHubMtbBarSize|0x100000|UINT32|0x30000008
+gSiPkgTokenSpaceGuid.PcdCpuTraceHubSwBarBase|0xfc000000|UINT32|0x30000009
+gSiPkgTokenSpaceGuid.PcdCpuTraceHubSwBarSize|0x800000|UINT32|0x3000000A
+gSiPkgTokenSpaceGuid.PcdCpuTraceHubRtitBarBase|0xfacfc000|UINT32|0x3000000B
+gSiPkgTokenSpaceGuid.PcdCpuTraceHubRtitBarSize|0x4000|UINT32|0x3000000C
+gSiPkgTokenSpaceGuid.PcdCpuTraceHubFwBarBase|0xfae00000|UINT32|0x3000000D
+gSiPkgTokenSpaceGuid.PcdCpuTraceHubFwBarSize|0x200000|UINT32|0x3000000E
+
+gSiPkgTokenSpaceGuid.PcdFspWrapperEnable    |FALSE|BOOLEAN|0x3000000F
+gSiPkgTokenSpaceGuid.PcdFspBinaryEnable|FALSE|BOOLEAN|0x30000010
+gSiPkgTokenSpaceGuid.PcdEmbeddedEnable|0x0|UINT8|0x30000012
+
+##
+## PcdEfiGcdAllocateType is using for EFI_GCD_ALLOCATE_TYPE selection
+## value of the struct
+##  0x00 EfiGcdAllocateAnySearchBottomUp
+##  0x01 EfiGcdAllocateMaxAddressSearchBottomUp
+##  0x03 EfiGcdAllocateAnySearchTopDown
+##  0x04 EfiGcdAllocateMaxAddressSearchTopDown
+##
+##  below value should not using in this situation
+##  0x05 EfiGcdMaxAllocateType : design for max value of struct
+##  0x02 EfiGcdAllocateAddress : design for speccification address allocate
+##
+gSiPkgTokenSpaceGuid.PcdEfiGcdAllocateType|0x01|UINT8|0x40000000
+
+##
+##  Handshake register value driven to DMA controller PCIE venodr specific configuration register from FW
+##  (LC/CM to host)
+##
+gSiPkgTokenSpaceGuid.PcdITbtToPcieRegister|0xEC|UINT8|0x40000003
+##
+##  Handshake register value driven from DMA controller PCIE venodr specific configuration register to FW
+##  (HOST to LC/CM)
+##
+gSiPkgTokenSpaceGuid.PcdPcieToITbtRegister|0xF0|UINT8|0x40000004
+
+gSiPkgTokenSpaceGuid.PcdAbove4GBMmioBase|0x0000004000000000|UINT64|0x40000005
+gSiPkgTokenSpaceGuid.PcdAbove4GBMmioSize|0x0000004000000000|UINT64|0x40000006
+
+gSiPkgTokenSpaceGuid.PcdSmmEntryPointBinFile|{ 0x52, 0xce, 0xc8, 0xe0, 0x51, 0x2b, 0xc2, 0x4c, 0xb3, 0xc7, 0xd2, 0x11, 0xa6, 0x25, 0xc1, 0xba }|VOID*|0x40000007
+gSiPkgTokenSpaceGuid.PcdSpsBinFile|{ 0xEE, 0xE3, 0x34, 0x71, 0xA6, 0x7F, 0x89, 0x44, 0x87, 0xA7, 0xAE, 0x38, 0x98, 0x4E, 0xAE, 0xD8 }|VOID*|0x40000008
+gSiPkgTokenSpaceGuid.PcdSpsSmmEntryPointBinFile|{ 0x5B, 0x63, 0x7D, 0x7C, 0x9C, 0x8B, 0x3C, 0x46, 0x9F, 0x7F, 0x91, 0xF6, 0x09, 0x06, 0x84, 0x8F }|VOID*|0x40000009
+gSiPkgTokenSpaceGuid.PcdSpaBinFile|{ 0xE1, 0x19, 0xB7, 0x7B, 0x2A, 0x53, 0x40, 0x7B, 0xA3, 0x4C, 0xC4, 0xF9, 0xE2, 0x6C, 0x27, 0x74 }|VOID*|0x4000000A
+gSiPkgTokenSpaceGuid.PcdSpaSmmEntryPointBinFile|{ 0xD7, 0xAD, 0xB2, 0x9F, 0x4D, 0x53, 0x4B, 0xA6, 0x8D, 0x55, 0x5D, 0x28, 0x91, 0x60, 0x10, 0x19 }|VOID*|0x4000000B
+
+##
+## - DpIn Silicon Feature
+##
+#  Note: PcdDpInEnable is Default Disable. Override it based on Platform/ CPU
+gSiPkgTokenSpaceGuid.PcdDpInEnable|FALSE|BOOLEAN|0x4000000C
+#  Note: For PcdMaxDpInExtPortSupported, we can have Maximum value of 0x08.
+#    Please Don't exceed beyond that. As it will cause boundary overflow.
+#    Currently hadrware wise maximum Dp-In External Port supported is 4.
+#    And it will never exceed the value of 0x08. That's why we don't support
+#    PcdMaxDpInExtPortSupported value more than 0x08
+gSiPkgTokenSpaceGuid.PcdMaxDpInExtPortSupported|0x4|UINT8|0x4000000D
+
+gSiPkgTokenSpaceGuid.VtdEngine1BaseAddeess|0xFED90000|UINT32|0x50000001
+gSiPkgTokenSpaceGuid.VtdEngine2BaseAddeess|0xFED92000|UINT32|0x50000002
+gSiPkgTokenSpaceGuid.VtdEngine3BaseAddeess|0xFED91000|UINT32|0x50000003
+gSiPkgTokenSpaceGuid.VtdEngine4BaseAddeess|0xFED84000|UINT32|0x50000004
+gSiPkgTokenSpaceGuid.VtdEngine5BaseAddeess|0xFED85000|UINT32|0x50000005
+gSiPkgTokenSpaceGuid.VtdEngine6BaseAddeess|0xFED86000|UINT32|0x50000006
+gSiPkgTokenSpaceGuid.VtdEngine7BaseAddeess|0xFED87000|UINT32|0x50000007
+##
+## Those PCDs are used to control build process.
+##
+gSiPkgTokenSpaceGuid.PcdTraceHubEnable               |FALSE|BOOLEAN|0xF0000001
+gSiPkgTokenSpaceGuid.PcdSmmVariableEnable            |FALSE|BOOLEAN|0xF0000002
+gSiPkgTokenSpaceGuid.PcdAtaEnable                    |FALSE|BOOLEAN|0xF0000004
+gSiPkgTokenSpaceGuid.PcdAcpiEnable                   |TRUE |BOOLEAN|0xF0000009
+gSiPkgTokenSpaceGuid.PcdSourceDebugEnable            |FALSE|BOOLEAN|0xF000000B
+gSiPkgTokenSpaceGuid.PcdPpmEnable                    |TRUE |BOOLEAN|0xF000000C
+gSiPkgTokenSpaceGuid.PcdIntegratedTouchEnable        |FALSE|BOOLEAN|0xF000000F
+gSiPkgTokenSpaceGuid.PcdPttEnable                    |FALSE|BOOLEAN|0xF0000011
+gSiPkgTokenSpaceGuid.PcdJhiEnable                    |FALSE|BOOLEAN|0xF0000012
+gSiPkgTokenSpaceGuid.PcdSoftwareGuardEnable          |FALSE|BOOLEAN|0xF0000013
+gSiPkgTokenSpaceGuid.PcdSmbiosEnable                 |TRUE |BOOLEAN|0xF0000014
+gSiPkgTokenSpaceGuid.PcdS3Enable                     |TRUE |BOOLEAN|0xF0000015
+gSiPkgTokenSpaceGuid.PcdOverclockEnable              |FALSE|BOOLEAN|0xF0000016
+gSiPkgTokenSpaceGuid.PcdCpuPowerOnConfigEnable       |FALSE|BOOLEAN|0xF0000017
+gSiPkgTokenSpaceGuid.PcdSsaFlagEnable                |FALSE|BOOLEAN|0xF0000018
+gSiPkgTokenSpaceGuid.PcdEvLoaderEnable               |FALSE|BOOLEAN|0xF0000019
+gSiPkgTokenSpaceGuid.PcdIgdEnable                    |TRUE |BOOLEAN|0xF000001A
+gSiPkgTokenSpaceGuid.PcdPegEnable                    |TRUE |BOOLEAN|0xF000001B
+gSiPkgTokenSpaceGuid.PcdSaDmiEnable                  |TRUE |BOOLEAN|0xF000001C
+gSiPkgTokenSpaceGuid.PcdGnaEnable                    |FALSE |BOOLEAN|0xF000001E
+gSiPkgTokenSpaceGuid.PcdVtdEnable                    |TRUE |BOOLEAN|0xF0000020
+gSiPkgTokenSpaceGuid.PcdBiosGuardEnable              |FALSE|BOOLEAN|0xF0000021
+gSiPkgTokenSpaceGuid.PcdSimicsEnable                 |FALSE|BOOLEAN|0xF0000022
+gSiPkgTokenSpaceGuid.PcdBdatEnable                   |FALSE|BOOLEAN|0xF0000023
+gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable       |TRUE |BOOLEAN|0xF0000024
+gSiPkgTokenSpaceGuid.PcdPeiDisplayEnable             |TRUE |BOOLEAN|0xF0000025
+gSiPkgTokenSpaceGuid.PcdOcWdtEnable                  |FALSE|BOOLEAN|0xF0000029
+gSiPkgTokenSpaceGuid.PcdMinTreeEnable                |FALSE|BOOLEAN|0xF000002A  # To separate modules used in mininal source tree and advanced features
+gSiPkgTokenSpaceGuid.PcdBootGuardEnable              |FALSE|BOOLEAN|0xF0000030
+gSiPkgTokenSpaceGuid.PcdSerialIoUartEnable           |FALSE|BOOLEAN|0xF0000033
+gSiPkgTokenSpaceGuid.PcdSiCatalogDebugEnable         |FALSE|BOOLEAN|0xF0000037
+gSiPkgTokenSpaceGuid.PcdBfxEnable                    |FALSE|BOOLEAN|0xF000003A
+gSiPkgTokenSpaceGuid.PcdThcEnable                    |FALSE|BOOLEAN|0xF000003B
+
+gSiPkgTokenSpaceGuid.PcdPpamEnable                   |FALSE|BOOLEAN|0xF000003F
+gSiPkgTokenSpaceGuid.PcdPsmiEnable                   |FALSE|BOOLEAN|0xF0000042
+gSiPkgTokenSpaceGuid.PcdCpuPcieEnable                |TRUE |BOOLEAN|0xF0000043
+gSiPkgTokenSpaceGuid.PcdHybridStorageSupport         |FALSE|BOOLEAN|0xF0000044
+gSiPkgTokenSpaceGuid.PcdMrcTraceMessageSupported     |TRUE |BOOLEAN|0xF0000045
+gSiPkgTokenSpaceGuid.PcdTmeLibSupported              |FALSE|BOOLEAN|0xF0000046
+gSiPkgTokenSpaceGuid.PcdAdlLpSupport                 |FALSE|BOOLEAN|0xF0000047
+gSiPkgTokenSpaceGuid.PcdSpsStateSaveEnable           |FALSE|BOOLEAN|0xF0000048
+gSiPkgTokenSpaceGuid.PcdSpaEnable                    |FALSE|BOOLEAN|0xF0000049
+
+## PCD for TraceHub
+[PcdsDynamic, PcdsPatchableInModule]
+## From MdeModulePkg.dec
+## Default OEM ID for ACPI table creation, its length must be 0x6 bytes to follow ACPI specification.
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemId|"INTEL "|VOID*|0x30001034
+## Default OEM Table ID for ACPI table creation, it is "EDK2    ".
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemTableId|0x20202020324B4445|UINT64|0x30001035
+## Default OEM Revision for ACPI table creation.
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemRevision|0x00000002|UINT32|0x30001036
+## Default Creator ID for ACPI table creation.
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorId|0x20202020|UINT32|0x30001037
+## Default Creator Revision for ACPI table creation.
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision|0x01000013|UINT32|0x30001038
+## ME HECI interface configuration
+gMeConfigSpaceGuid.PcdHeciDumpsEnabled|TRUE|BOOLEAN|0x50000001
+gMeConfigSpaceGuid.PcdHeciTimeoutsEnabled|TRUE|BOOLEAN|0x50000002
+
+
+[PcdsFixedAtBuild, PcdsPatchableInModule]
+## This value is used to set the base address of PCH devices
+gSiPkgTokenSpaceGuid.PcdSmbusBaseAddress|0x0000EFA0|UINT16|0x00010031
+gSiPkgTokenSpaceGuid.PcdTcoBaseAddress|0x0400|UINT16|0x00010033
+gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress|0x1800|UINT16|0x00010035
+
+
+## Stack size in the temporary RAM.
+## 0 means half of TemporaryRamSize.
+gSiPkgTokenSpaceGuid.PcdPeiTemporaryRamStackSize|0|UINT32|0x00010036
+##
+## PcdFviSmbiosType determines the SMBIOS OEM type (0x80 to 0xFF) defined in SMBIOS,
+## values 0-0x7F will be treated as disable FVI reporting.
+## FVI structure uses it as SMBIOS OEM type to provide version information.
+##
+gSiPkgTokenSpaceGuid.PcdFviSmbiosType|0xDD|UINT8|0x00010037
+gSiPkgTokenSpaceGuid.PcdSaPciPrint|FALSE|BOOLEAN|0x00010039
+##
+## SMBIOS defaults
+##
+gSiPkgTokenSpaceGuid.PcdSmbiosDefaultSocketDesignation|"U3E1"|VOID*|0x0001003a
+gSiPkgTokenSpaceGuid.PcdSmbiosDefaultSerialNumber|"To Be Filled By O.E.M."|VOID*|0x0001003b
+gSiPkgTokenSpaceGuid.PcdSmbiosDefaultAssetTag|"To Be Filled By O.E.M."|VOID*|0x0001003c
+gSiPkgTokenSpaceGuid.PcdSmbiosDefaultPartNumber|"To Be Filled By O.E.M."|VOID*|0x0001003d
+
+##
+## Allocate 56 KB [0x2000..0xFFFF] of I/O space for Pci Devices
+## If PcdPciReservedMemLimit =0  Pci Reserved default  MMIO Limit is 0xE0000000 else use PcdPciReservedMemLimit .
+##
+gSiPkgTokenSpaceGuid.PcdPciReservedIobase       |0x2000 |UINT16|0x00010041
+gSiPkgTokenSpaceGuid.PcdPciReservedIoLimit      |0xFFFF |UINT16|0x00010042
+gSiPkgTokenSpaceGuid.PcdPciReservedMemLimit     |0x0000 |UINT32|0x00010043
+gSiPkgTokenSpaceGuid.PcdPciDmaAbove4G           |FALSE |BOOLEAN|0x00010044
+gSiPkgTokenSpaceGuid.PcdPciNoExtendedConfigSpace|FALSE |BOOLEAN|0x00010045
+
+##
+## Default 8MB TSEG for Release build BIOS when IED disabled (Also a default)
+##
+gSiPkgTokenSpaceGuid.PcdTsegSize|0x00800000|UINT32|0x00010046
+##
+## gSiPkgTokenSpaceGuid.PcdFwStsSmbiosType determines the SMBIOS OEM type (0x80 to 0xFF) defined
+## in SMBIOS, values 0-0x7F will be treated as disable FWSTS SMBIOS reporting.
+## FWSTS structure uses it as SMBIOS OEM type to provide FWSTS information.
+##
+gSiPkgTokenSpaceGuid.PcdFwStsSmbiosType|0xDB|UINT8|0x00010047
+
+##
+## Maximum Address the AP Wakeup Buffer can start.
+##
+gSiPkgTokenSpaceGuid.PcdCpuApWakeupBufferMaxAddr|0x58000|UINT32|0x00010048
+
+##
+## Silicon Reference Code versions
+##
+##Revision:Weekly build number
+gSiPkgTokenSpaceGuid.PcdSiliconInitVersionRevision|0x33|UINT8|0x00010051
+
+##Build[7:4]:Daily build number.
+##Build[3:0]:Patch build number.
+
+##
+## Temp MEM IO resource
+##
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempPciBusMin    |2         |UINT8 |0x00010053
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempPciBusMax    |10        |UINT8 |0x00010054
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempMemBaseAddr  |0xFE600000|UINT32|0x00010055
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempMemSize      |0x00200000|UINT32|0x00010056
+
+##
+## This PCD specifies the base address of the HPET timer.
+## The acceptable values are 0xFED00000, 0xFED01000, 0xFED02000, and 0xFED03000
+##
+gSiPkgTokenSpaceGuid.PcdSiHpetBaseAddress    |0xFED00000|UINT32|0x00010057
+##
+## This PCD specifies the base address of the IO APIC.
+## The acceptable values are 0xFECxx000.
+##
+gSiPkgTokenSpaceGuid.PcdSiIoApicBaseAddress  |0xFEC00000|UINT32|0x00010058
+
+
+##
+## VTD Base Addresses
+##
+
+## Null-terminated string of the Version of Physical Presence interface supported by platform.
+# @Prompt Version of Physical Presence interface supported by platform.
+gSiPkgTokenSpaceGuid.PcdTcgPhysicalPresenceInterfaceVer|"1.3"|VOID*|0x00000008
+
+## This PCD specifies Master of TraceHub device
+gSiPkgTokenSpaceGuid.PcdTraceHubDebugLibMaster|0x0|UINT32|0x00011000
+## This PCD specifies Channel of TraceHub device
+gSiPkgTokenSpaceGuid.PcdTraceHubDebugLibChannel|0x0|UINT32|0x00011001
+
+
+[PcdsPatchableInModule, PcdsFixedAtBuild]
+## This value is used to set the base address of MCH
+gSiPkgTokenSpaceGuid.PcdMchBaseAddress|0xFEDC0000|UINT64|0x00010030
+## 128KB window
+gSiPkgTokenSpaceGuid.PcdMchMmioSize|0x20000|UINT32|0x50000000
+gSiPkgTokenSpaceGuid.PcdSiliconInitVersionMajor   |0x0A|UINT8|0x00010049
+gSiPkgTokenSpaceGuid.PcdSiliconInitVersionValue   |0x0000000800260020|UINT64|0x00010077
+
+##Minor:the program that supported by same core generation.
+gSiPkgTokenSpaceGuid.PcdSiliconInitVersionMinor   |0x00|UINT8|0x00010050
+
+gSiPkgTokenSpaceGuid.PcdSiliconInitVersionBuild   |0x10|UINT8|0x00010052
+gSiPkgTokenSpaceGuid.PcdRegBarBaseAddress|0xFB000000|UINT32|0x00010059
+[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
+##
+## SerialIo Uart Configuration
+##
+gSiPkgTokenSpaceGuid.PcdSerialIoUartDebugEnable   |0          |UINT8 |0x00210001 # 0:Disable, 1:Enable and Initialize, 2:Enable without Initializing
+gSiPkgTokenSpaceGuid.PcdSerialIoUartNumber        |2          |UINT8 |0x00210002
+gSiPkgTokenSpaceGuid.PcdSerialIoUartMode          |2          |UINT8 |0x00210003 # 0:Disabled, 1:Enabled, 2:Hidden, 3:COM, 4:SkipInit
+gSiPkgTokenSpaceGuid.PcdSerialIoUartBaudRate      |115200     |UINT32|0x00210004 # 0:Default, Max:6000000
+gSiPkgTokenSpaceGuid.PcdSerialIoUartParity        |1          |UINT8 |0x00210008 # 0:DefaultParity, 1:NoParity, 2:EvenParity, 3:OddParity
+gSiPkgTokenSpaceGuid.PcdSerialIoUartDataBits      |8          |UINT8 |0x00210009 # 0:Default, 5,6,7,8
+gSiPkgTokenSpaceGuid.PcdSerialIoUartStopBits      |1          |UINT8 |0x0021000A # 0:DefaultStopBits, 1:OneStopBit, 2:OneFiveStopBits, 3:TwoStopBits
+gSiPkgTokenSpaceGuid.PcdSerialIoUartAutoFlow      |0          |UINT8 |0x0021000B # 0:No HW flow control, Only RX/TX Enabled; 1:HW Flow Control On, Rts/Cts lines enabled;
+gSiPkgTokenSpaceGuid.PcdSerialIoUartRxPinMux      |0x0        |UINT32|0x0021000C # Pin muxing config for UART Rx pin
+gSiPkgTokenSpaceGuid.PcdSerialIoUartTxPinMux      |0x0        |UINT32|0x00210010 # Pin muxing config for UART Tx pin
+gSiPkgTokenSpaceGuid.PcdSerialIoUartRtsPinMux     |0x0        |UINT32|0x00210014 # Pin muxing config for UART Rts pin
+gSiPkgTokenSpaceGuid.PcdSerialIoUartCtsPinMux     |0x0        |UINT32|0x00210018 # Pin muxing config for UART Cts pin
+gSiPkgTokenSpaceGuid.PcdSerialIoUartDebugMmioBase |0xFE036000 |UINT32|0x0021001C # PcdSerialIoUartMode = Enabled, need to assign MMIO Resource in SEC/PEI Phase
+
+gSiPkgTokenSpaceGuid.PcdLpcUartDebugEnable        |0x1        |UINT8 |0x00210026 # 0:Disable, 1:Enable
+gSiPkgTokenSpaceGuid.PcdDebugInterfaceFlags       |0x12       |UINT8 |0x00210027 # BIT0-RAM, BIT1-UART, BIT3-USB3, BIT4-Serial IO, BIT5-TraceHub, BIT2 - Not used.
+gSiPkgTokenSpaceGuid.PcdSerialDebugLevel          |0x3        |UINT8 |0x00210028 # {0:Disable, 1:Error Only, 2:Error and Warnings, 3:Load Error Warnings and Info, 4:Load Error Warnings and Info, 5:Load Error Warnings Info and Verbose
+gSiPkgTokenSpaceGuid.PcdIsaSerialUartBase         |0x0        |UINT8 |0x00210029 # 0:0x3F8, 1:0x2F8
+
+## UART Lib TimeOut
+gSiPkgTokenSpaceGuid.PcdSerialIoUartTimeOut             |1000000 |UINT32 |0x00210020 # Write TimeOut in Micro Seconds - 0 = disabbled, default 1 second,
+gSiPkgTokenSpaceGuid.PcdSerialIoUartLibSkipMmioCheck    |FALSE   |BOOLEAN|0x00210024 # If TRUE MMIO sanity checks are skipped
+
+## UART Dxe Driver IgnoreBaudRateSet
+## TRUE - Blocks changing BaudRate, so that driver will not override UART's initial configuration.
+##        Required to support redirection on higher BaudRates.
+## FALSE - Allows for UART settings to be changed through the Serial Io Protocol
+##
+gSiPkgTokenSpaceGuid.PcdSerialIoUartDriverIgnoreBaudRateSet|FALSE|BOOLEAN|0x00210025
+
+##
+## SerialIo 2nd Uart Configuration
+##
+gSiPkgTokenSpaceGuid.PcdSerialIo2ndUartEnable    |0          |UINT8 |0x0021002A # 0:Disable, 1:Enable and Initialize, 2:Enable without Initializing
+gSiPkgTokenSpaceGuid.PcdSerialIo2ndUartNumber    |2          |UINT8 |0x0021002B
+gSiPkgTokenSpaceGuid.PcdSerialIo2ndUartMode      |2          |UINT8 |0x0021002C # 0:Disabled, 1:Enabled, 2:Hidden, 3:COM, 4:SkipInit
+gSiPkgTokenSpaceGuid.PcdSerialIo2ndUartBaudRate  |115200     |UINT32|0x0021002D # 0:Default, Max:6000000
+gSiPkgTokenSpaceGuid.PcdSerialIo2ndUartParity    |1          |UINT8 |0x00210031 # 0:DefaultParity, 1:NoParity, 2:EvenParity, 3:OddParity
+gSiPkgTokenSpaceGuid.PcdSerialIo2ndUartDataBits  |8          |UINT8 |0x00210032 # 0:Default, 5,6,7,8
+gSiPkgTokenSpaceGuid.PcdSerialIo2ndUartStopBits  |1          |UINT8 |0x00210033 # 0:DefaultStopBits, 1:OneStopBit, 2:OneFiveStopBits, 3:TwoStopBits
+gSiPkgTokenSpaceGuid.PcdSerialIo2ndUartAutoFlow  |0          |UINT8 |0x00210034 # 0:No HW flow control, Only RX/TX Enabled; 1:HW Flow Control On, Rts/Cts lines enabled;
+gSiPkgTokenSpaceGuid.PcdSerialIo2ndUartRxPinMux  |0x0        |UINT32|0x00210035 # Pin muxing config for UART Rx pin
+gSiPkgTokenSpaceGuid.PcdSerialIo2ndUartTxPinMux  |0x0        |UINT32|0x00210039 # Pin muxing config for UART Tx pin
+gSiPkgTokenSpaceGuid.PcdSerialIo2ndUartRtsPinMux |0x0        |UINT32|0x0021003D # Pin muxing config for UART Rts pin
+gSiPkgTokenSpaceGuid.PcdSerialIo2ndUartCtsPinMux |0x0        |UINT32|0x00210041 # Pin muxing config for UART Cts pin
+gSiPkgTokenSpaceGuid.PcdSerialIo2ndUartMmioBase  |0xFE034000 |UINT32|0x00210045 # PcdSerialIoUartMode = Enabled, need to assign MMIO Resource in SEC/PEI Phase
+
+##
+## PCI Express MMIO region length
+## Valid settings: 0x20000000/512MB, 0x10000000/256MB, 0x8000000/128MB, 0x4000000/64MB
+##
+gSiPkgTokenSpaceGuid.PcdPciExpressRegionLength|0x10000000|UINT32|0x00200001
+##
+## Typically this should be the same with gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress.
+## This PCD is added for supporting different PCD type in different phases.
+##
+gSiPkgTokenSpaceGuid.PcdSiPciExpressBaseAddress |0xC0000000|UINT64|0x00200002
+##
+## PCI Express MMIO temporary region length in SEC phase.
+## Valid settings: 0x20000000/512MB, 0x10000000/256MB, 0x8000000/128MB, 0x4000000/64MB
+##
+gSiPkgTokenSpaceGuid.PcdTemporaryPciExpressRegionLength|0x10000000|UINT32|0x00200005
+
+## Specifies the SMRR2 base address.<BR><BR>
+# @Prompt SMRR2 base address.
+# @Expression  0x80000001 | (gSiPkgTokenSpaceGuid.PcdCpuSmmSmrr2Base & 0xfff) == 0
+gSiPkgTokenSpaceGuid.PcdCpuSmmSmrr2Base|0|UINT32|0x20000002
+
+## Specifies the SMRR2 range size.<BR><BR>
+# @Prompt SMRR2 range size.
+# @Expression  0x80000001 | (gSiPkgTokenSpaceGuid.PcdCpuSmmSmrr2Size & 0xfff) == 0
+gSiPkgTokenSpaceGuid.PcdCpuSmmSmrr2Size|0|UINT32|0x20000003
+
+## Specifies the SMRR2 range cache type.
+#  If SMRR2 is used to map a flash/ROM based handler, it would be configured as WP.<BR><BR>
+#  5: WP(Write Protect).<BR>
+#  6: WB(Write Back).<BR>
+# @Prompt SMRR2 range cache type.
+gSiPkgTokenSpaceGuid.PcdCpuSmmSmrr2CacheType|5|UINT8|0x20000004
+
+## Indidates if SMM PROT MODE feature is supported.<BR><BR>
+#   TRUE  - SMM PROT MODE feature is supported.<BR>
+#   FALSE - SMM PROT MODE feature is not supported.<BR>
+# @Prompt  SMM PROT MODE feature.
+gSiPkgTokenSpaceGuid.PcdCpuSmmProtectedModeEnable|FALSE|BOOLEAN|0x20000008
+
+## Specifies the a size of memory region to reserve in SMM for testing only.
+#  One can look in BIOS serial log for PCD to get region base address.
+#  Note: A different region may be allocated in release build than debug build.
+# @Prompt SMM test region size.\r
+gSiPkgTokenSpaceGuid.PcdSmmTestRsvMemorySize|0x0|UINT32|0x2000000E
+
+[PcdsDynamic]
+
+## Indidates if SMM Code Access Check feature is supported.<BR><BR>
+#   TRUE  - SMM Code Access Check feature is supported.<BR>
+#   FALSE - SMM Code Access Check feature is not supported.<BR>
+# @Prompt  SMM Code Access Check feature.
+gSiPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable|TRUE|BOOLEAN|0x001000D
+
+## Causes all UEFI variables to be treated as volatile and hence never written to non-volatile
+## storage.
+## This is useful in cases such as a simulation environment that does not emulate a non-volatile
+## storage device or in recovery scenarios where system errors prevent non-volatile storage from being accessed
+gSiPkgTokenSpaceGuid.PcdNvVariableEmulationMode|FALSE|BOOLEAN|0x0010000E
+
+## Enables or disables storage of UEFI variables using the CSE Variable Storage drivers
+##   If disabled at runtime, it must be set before the CSE Variable Storage driver loads.
+gSiPkgTokenSpaceGuid.PcdEnableCseVariableStorage|FALSE|BOOLEAN|0x0010000F
+
+## Enables or disables storage of UEFI variables using the FVB Variable Storage drivers
+##  If disabled at runtime, it must be set before the FVB Variable Storage driver loads.
+gSiPkgTokenSpaceGuid.PcdEnableFvbVariableStorage|TRUE|BOOLEAN|0x00100010
+
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 02/40] TigerlakeSiliconPkg/Include: Add Library, PPI and Protocol include headers
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 03/40] TigerlakeSiliconPkg/Include: Add Pins, Register and other " Heng Luo
                   ` (37 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following header files:
  * Include/Library
  * Include/Ppi
  * Include/Protocol

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/Include/Library/ConfigBlockLib.h       |  64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Library/CpuRegbarAccessLib.h   | 332 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Library/DxeHdaNhltLib.h        | 153 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Library/EspiLib.h              | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Library/GbeLib.h               |  63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Library/GpioConfig.h           | 342 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Library/GpioLib.h              | 720 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Library/GpioNativeLib.h        | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Library/MmPciLib.h             |  27 +++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Library/PchPcieRpLib.h         | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Library/PchPcrLib.h            | 256 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Library/PcieHelperLib.h        | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Library/PmcLib.h               | 355 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Library/ResetSystemLib.h       |  79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Library/SataLib.h              | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Library/SerialIoAccessLib.h    | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Library/SiConfigBlockLib.h     |  56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Library/SpiAccessLib.h         | 290 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Library/VtdInfoLib.h           |  53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Ppi/PeiPreMemSiDefaultPolicy.h |  34 ++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Ppi/PeiSiDefaultPolicy.h       |  33 +++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Ppi/SiPolicy.h                 |  75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Protocol/GopComponentName2.h   |  61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Protocol/GopPolicy.h           |  73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Protocol/IgdOpRegion.h         |  22 ++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Protocol/Spi.h                 | 301 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 26 files changed, 4199 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/ConfigBlockLib.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/ConfigBlockLib.h
new file mode 100644
index 0000000000..dbf786ec9a
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/ConfigBlockLib.h
@@ -0,0 +1,64 @@
+/** @file
+  Header file for Config Block Lib implementation
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CONFIG_BLOCK_LIB_H_
+#define _CONFIG_BLOCK_LIB_H_
+
+/**
+  Create config block table
+
+  @param[in]     TotalSize                    - Max size to be allocated for the Config Block Table
+  @param[out]    ConfigBlockTableAddress      - On return, points to a pointer to the beginning of Config Block Table Address
+
+  @retval EFI_INVALID_PARAMETER - Invalid Parameter
+  @retval EFI_OUT_OF_RESOURCES  - Out of resources
+  @retval EFI_SUCCESS           - Successfully created Config Block Table at ConfigBlockTableAddress
+**/
+EFI_STATUS
+EFIAPI
+CreateConfigBlockTable (
+  IN     UINT16    TotalSize,
+  OUT    VOID      **ConfigBlockTableAddress
+  );
+
+/**
+  Add config block into config block table structure
+
+  @param[in]     ConfigBlockTableAddress      - A pointer to the beginning of Config Block Table Address
+  @param[out]    ConfigBlockAddress           - On return, points to a pointer to the beginning of Config Block Address
+
+  @retval EFI_OUT_OF_RESOURCES - Config Block Table is full and cannot add new Config Block or
+                                 Config Block Offset Table is full and cannot add new Config Block.
+  @retval EFI_SUCCESS          - Successfully added Config Block
+**/
+EFI_STATUS
+EFIAPI
+AddConfigBlock (
+  IN     VOID      *ConfigBlockTableAddress,
+  OUT    VOID      **ConfigBlockAddress
+  );
+
+/**
+  Retrieve a specific Config Block data by GUID
+
+  @param[in]      ConfigBlockTableAddress      - A pointer to the beginning of Config Block Table Address
+  @param[in]      ConfigBlockGuid              - A pointer to the GUID uses to search specific Config Block
+  @param[out]     ConfigBlockAddress           - On return, points to a pointer to the beginning of Config Block Address
+
+  @retval EFI_NOT_FOUND         - Could not find the Config Block
+  @retval EFI_SUCCESS           - Config Block found and return
+**/
+EFI_STATUS
+EFIAPI
+GetConfigBlock (
+  IN     VOID      *ConfigBlockTableAddress,
+  IN     EFI_GUID  *ConfigBlockGuid,
+  OUT    VOID      **ConfigBlockAddress
+  );
+
+#endif // _CONFIG_BLOCK_LIB_H_
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/CpuRegbarAccessLib.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/CpuRegbarAccessLib.h
new file mode 100644
index 0000000000..564fcccb43
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/CpuRegbarAccessLib.h
@@ -0,0 +1,332 @@
+/** @file
+  Header file for CPU REGBAR ACCESS library.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _CPU_REGBAR_ACCESS_LIB_H_
+#define _CPU_REGBAR_ACCESS_LIB_H_
+
+#define INVALID_DATA_64  0xFFFFFFFFFFFFFFFF
+#define INVALID_DATA_32  0xFFFFFFFF
+#define INVALID_DATA_16  0xFFFF
+#define INVALID_DATA_8   0xFF
+#define INVALID_PID      0xFF
+
+typedef UINT8    CPU_SB_DEVICE_PID;
+
+/**
+  Read REGBAR register.
+  It returns REGBAR register and size in 8bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid      CPU SB Device Port ID
+  @param[in]  Offset              Register offset of this Port ID
+
+  @retval     UINT64           REGBAR register value.
+**/
+UINT64
+CpuRegbarRead64 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset
+  );
+
+
+/**
+  Read REGBAR register.
+  It returns REGBAR register and size in 4bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid      CPU SB Device Port ID
+  @param[in]  Offset              Register offset of this Port ID
+
+  @retval     UINT32           REGBAR register value.
+**/
+UINT32
+CpuRegbarRead32 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset
+  );
+
+/**
+  Read REGBAR register.
+  It returns REGBAR register and size in 2bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid      CPU SB Device Port ID
+  @param[in]  Offset              Register offset of this Port ID
+
+  @retval     UINT16           REGBAR register value.
+**/
+UINT16
+CpuRegbarRead16 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset
+  );
+
+/**
+  Read REGBAR register.
+  It returns REGBAR register and size in 1bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid      CPU SB Device Port ID
+  @param[in]  Offset              Register offset of this Port ID
+
+  @retval     UINT8            REGBAR regsiter value
+**/
+UINT8
+CpuRegbarRead8 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset
+  );
+
+/**
+  Write REGBAR register.
+  It programs REGBAR register and size in 8bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid      CPU SB Device Port ID
+  @param[in]  Offset              Register offset of Port ID.
+  @param[in]  Data             Input Data. Must be the same size as Size parameter.
+
+  @retval     UINT64           Value written to register
+**/
+UINT64
+CpuRegbarWrite64 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT64                            Data
+  );
+
+
+/**
+  Write REGBAR register.
+  It programs REGBAR register and size in 4bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid      CPU SB Device Port ID
+  @param[in]  Offset           Register offset of Port ID.
+  @param[in]  Data             Input Data. Must be the same size as Size parameter.
+
+  @retval     UINT32           Value written to register
+**/
+UINT32
+CpuRegbarWrite32 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT32                            Data
+  );
+
+/**
+  Write REGBAR register.
+  It programs REGBAR register and size in 2bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid      CPU SB Device Port ID
+  @param[in]  Offset           Register offset of Port ID.
+  @param[in]  Data             Input Data. Must be the same size as Size parameter.
+
+  @retval     UINT16           Value written to register
+**/
+UINT16
+CpuRegbarWrite16 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT16                            Data
+  );
+
+/**
+  Write REGBAR register.
+  It programs REGBAR register and size in 1bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid      CPU SB Device Port ID
+  @param[in]  Offset           Register offset of Port ID.
+  @param[in]  Data             Input Data. Must be the same size as Size parameter.
+
+  @retval     UINT8            Value written to register
+**/
+UINT8
+CpuRegbarWrite8 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT8                             Data
+  );
+
+/**
+  Write REGBAR register.
+  It programs REGBAR register and size in 4bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid      CPU SB Device Port ID
+  @param[in]  Offset           Register offset of Port ID.
+  @param[in]  OrData           OR Data. Must be the same size as Size parameter.
+
+  @retval     UINT32           Value written to register
+
+**/
+UINT32
+CpuRegbarOr32 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT32                            OrData
+  );
+
+/**
+  Write REGBAR register.
+  It programs REGBAR register and size in 2bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid   CPU SB Device Port ID
+  @param[in]  Offset           Register offset of Port ID.
+  @param[in]  OrData           OR Data. Must be the same size as Size parameter.
+
+  @retval     UINT16           Value written to register
+
+**/
+UINT16
+CpuRegbarOr16 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT16                            OrData
+  );
+
+/**
+  Write REGBAR register.
+  It programs REGBAR register and size in 1bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid      CPU SB Device Port ID
+  @param[in]  Offset           Register offset of Port ID.
+  @param[in]  OrData           OR Data. Must be the same size as Size parameter.
+
+  @retval     UINT8            Value written to register
+
+**/
+UINT8
+CpuRegbarOr8 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT8                             OrData
+  );
+
+/**
+  Performs a bitwise AND of a 32-bit data.
+  It programs REGBAR register and size in 4bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevice      CPU SB Device
+  @param[in]  Offset           Register offset of Port ID.
+  @param[in]  AndData          And Data. Must be the same size as Size parameter.
+
+  @retval     UINT32           Value written to register
+
+**/
+UINT32
+CpuRegbarAnd32 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT32                            AndData
+  );
+
+/**
+  Performs a bitwise AND of a 16-bit data.
+  It programs REGBAR register and size in 2bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevice      CPU SB Device
+  @param[in]  Offset           Register offset of Port ID.
+  @param[in]  AndData          And Data. Must be the same size as Size parameter.
+
+  @retval     UINT16           Value written to register
+
+**/
+UINT16
+CpuRegbarAnd16 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT16                            AndData
+  );
+
+/**
+  Performs a bitwise AND of a 8-bit data.
+  It programs REGBAR register and size in 1byte.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevice      CPU SB Device
+  @param[in]  Offset           Register offset of Port ID.
+  @param[in]  AndData          And Data. Must be the same size as Size parameter.
+
+  @retval     UINT8            Value written to register
+
+**/
+UINT8
+CpuRegbarAnd8 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT8                             AndData
+  );
+/**
+  Write REGBAR register.
+  It programs REGBAR register and size in 4bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid      CPU SB Device Port ID
+  @param[in]  Offset           Register offset of Port ID.
+  @param[in]  AndData          AND Data. Must be the same size as Size parameter.
+  @param[in]  OrData           OR Data. Must be the same size as Size parameter.
+
+  @retval     UINT32           Value written to register
+
+**/
+UINT32
+CpuRegbarAndThenOr32 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT32                            AndData,
+  IN  UINT32                            OrData
+  );
+
+/**
+  Write REGBAR register.
+  It programs REGBAR register and size in 2bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid      CPU SB Device Port ID
+  @param[in]  Offset           Register offset of Port ID.
+  @param[in]  AndData          AND Data. Must be the same size as Size parameter.
+  @param[in]  OrData           OR Data. Must be the same size as Size parameter.
+
+  @retval     UINT16           Value written to register
+
+**/
+UINT16
+CpuRegbarAndThenOr16 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT16                            AndData,
+  IN  UINT16                            OrData
+  );
+
+/**
+  Write REGBAR register.
+  It programs REGBAR register and size in 1bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid      CPU SB Device Port ID
+  @param[in]  Offset           Register offset of Port ID.
+  @param[in]  AndData          AND Data. Must be the same size as Size parameter.
+  @param[in]  OrData           OR Data. Must be the same size as Size parameter.
+
+  @retval     UINT8            Value written to register
+
+**/
+UINT8
+CpuRegbarAndThenOr8 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT8                             AndData,
+  IN  UINT8                             OrData
+  );
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/DxeHdaNhltLib.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/DxeHdaNhltLib.h
new file mode 100644
index 0000000000..c48ea3667f
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/DxeHdaNhltLib.h
@@ -0,0 +1,153 @@
+/** @file
+  Prototype of the DxePchHdaNhltLib library.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_HDA_NHLT_LIB_H_
+#define _DXE_HDA_NHLT_LIB_H_
+
+#include <DxeHdaNhlt.h>
+
+/**
+  Returns pointer to Endpoint ENDPOINT_DESCRIPTOR structure.
+
+  @param[in] *NhltTable    Endpoint for which Format address is retrieved
+  @param[in] FormatIndex   Index of Format to be retrieved
+
+  @retval                  Pointer to ENDPOINT_DESCRIPTOR structure with given index
+**/
+ENDPOINT_DESCRIPTOR *
+GetNhltEndpoint (
+  IN CONST NHLT_ACPI_TABLE      *NhltTable,
+  IN CONST UINT8                EndpointIndex
+  );
+
+/**
+  Returns pointer to Endpoint Specific Configuration SPECIFIC_CONFIG structure.
+
+  @param[in] *Endpoint     Endpoint for which config address is retrieved
+
+  @retval                  Pointer to SPECIFIC_CONFIG structure with endpoint's capabilities
+**/
+SPECIFIC_CONFIG *
+GetNhltEndpointDeviceCapabilities (
+  IN CONST ENDPOINT_DESCRIPTOR  *Endpoint
+  );
+
+/**
+  Returns pointer to all Formats Configuration FORMATS_CONFIG structure.
+
+  @param[in] *Endpoint     Endpoint for which Formats address is retrieved
+
+  @retval                  Pointer to FORMATS_CONFIG structure
+**/
+FORMATS_CONFIG *
+GetNhltEndpointFormatsConfig (
+  IN CONST ENDPOINT_DESCRIPTOR  *Endpoint
+  );
+
+/**
+  Returns pointer to Format Configuration FORMAT_CONFIG structure.
+
+  @param[in] *Endpoint     Endpoint for which Format address is retrieved
+  @param[in] FormatIndex   Index of Format to be retrieved
+
+  @retval                  Pointer to FORMAT_CONFIG structure with given index
+**/
+FORMAT_CONFIG *
+GetNhltEndpointFormat (
+  IN CONST ENDPOINT_DESCRIPTOR  *Endpoint,
+  IN CONST UINT8                FormatIndex
+  );
+
+/**
+  Returns pointer to all Device Information DEVICES_INFO structure.
+
+  @param[in] *Endpoint     Endpoint for which DevicesInfo address is retrieved
+
+  @retval                  Pointer to DEVICES_INFO structure
+**/
+DEVICES_INFO *
+GetNhltEndpointDevicesInfo (
+  IN CONST ENDPOINT_DESCRIPTOR  *Endpoint
+  );
+
+/**
+  Returns pointer to Device Information DEVICES_INFO structure.
+
+  @param[in] *Endpoint       Endpoint for which Device Info address is retrieved
+  @param[in] DeviceInfoIndex Index of Device Info to be retrieved
+
+  @retval                    Pointer to DEVICE_INFO structure with given index
+**/
+DEVICE_INFO *
+GetNhltEndpointDeviceInfo (
+  IN CONST ENDPOINT_DESCRIPTOR  *Endpoint,
+  IN CONST UINT8                DeviceInfoIndex
+  );
+
+
+/**
+  Returns pointer to OED Configuration SPECIFIC_CONFIG structure.
+
+  @param[in] *NhltTable    NHLT table for which OED address is retrieved
+
+  @retval                  Pointer to SPECIFIC_CONFIG structure with NHLT capabilities
+**/
+SPECIFIC_CONFIG *
+GetNhltOedConfig (
+  IN CONST NHLT_ACPI_TABLE      *NhltTable
+  );
+
+/**
+  Prints Format configuration.
+
+  @param[in] *Format       Format to be printed
+
+  @retval None
+**/
+VOID
+NhltFormatDump (
+  IN CONST FORMAT_CONFIG        *Format
+  );
+
+
+/**
+  Prints Endpoint configuration.
+
+  @param[in] *Endpoint     Endpoint to be printed
+
+  @retval None
+**/
+VOID
+NhltEndpointDump (
+  IN CONST ENDPOINT_DESCRIPTOR  *Endpoint
+  );
+
+/**
+  Prints OED (Offload Engine Driver) configuration.
+
+  @param[in] *OedConfig   OED to be printed
+
+  @retval None
+**/
+VOID
+NhltOedConfigDump (
+  IN CONST SPECIFIC_CONFIG      *OedConfig
+  );
+
+/**
+  Prints NHLT (Non HDA-Link Table) to be exposed via ACPI (aka. OED (Offload Engine Driver) Configuration Table).
+
+  @param[in] *NhltTable    The NHLT table to print
+
+  @retval None
+**/
+VOID
+NhltAcpiTableDump (
+  IN NHLT_ACPI_TABLE            *NhltTable
+  );
+
+#endif // _DXE_HDA_NHLT_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/EspiLib.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/EspiLib.h
new file mode 100644
index 0000000000..6d8466ab7a
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/EspiLib.h
@@ -0,0 +1,140 @@
+/** @file
+  Header file for PchEspiLib.
+  All function in this library is available for PEI, DXE, and SMM,
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _ESPI_LIB_H_
+#define _ESPI_LIB_H_
+
+/**
+  Checks if there's second slave connected under CS#1
+
+  @retval TRUE      There's second slave
+  @retval FALSE     There's no second slave
+**/
+BOOLEAN
+IsEspiSecondSlaveSupported (
+  VOID
+  );
+
+/**
+  Checks in slave General Capabilities register if it supports channel with requested number
+
+  @param[in]  SlaveId         Id of slave to check
+  @param[in]  ChannelNumber   Number of channel of which to check
+
+  @retval TRUE      Channel with requested number is supported by slave device
+  @retval FALSE     Channel with requested number is not supported by slave device
+**/
+BOOLEAN
+IsEspiSlaveChannelSupported (
+  UINT8   SlaveId,
+  UINT8   ChannelNumber
+  );
+
+/**
+  Is eSPI enabled in strap.
+
+  @retval TRUE          Espi is enabled in strap
+  @retval FALSE         Espi is disabled in strap
+**/
+BOOLEAN
+IsEspiEnabled (
+  VOID
+  );
+
+/**
+  Get configuration from eSPI slave
+
+  @param[in]  SlaveId       eSPI slave ID
+  @param[in]  SlaveAddress  Slave Configuration Register Address
+  @param[out] OutData       Configuration data read
+
+  @retval EFI_SUCCESS           Operation succeed
+  @retval EFI_INVALID_PARAMETER Slave ID is not supported
+  @retval EFI_INVALID_PARAMETER Slave ID is not supported or SlaveId 1 is used in PchLp
+  @retval EFI_INVALID_PARAMETER Slave configuration register address exceed maximum allowed
+  @retval EFI_INVALID_PARAMETER Slave configuration register address is not DWord aligned
+  @retval EFI_DEVICE_ERROR      Error in SCRS during polling stage of operation
+**/
+EFI_STATUS
+PchEspiSlaveGetConfig (
+  IN  UINT32 SlaveId,
+  IN  UINT32 SlaveAddress,
+  OUT UINT32 *OutData
+  );
+
+/**
+  Set eSPI slave configuration
+
+  Note: A Set_Configuration must always be followed by a Get_Configuration in order to ensure
+  that the internal state of the eSPI-MC is consistent with the Slave's register settings.
+
+  @param[in]  SlaveId       eSPI slave ID
+  @param[in]  SlaveAddress  Slave Configuration Register Address
+  @param[in]  InData        Configuration data to write
+
+  @retval EFI_SUCCESS           Operation succeed
+  @retval EFI_INVALID_PARAMETER Slave ID is not supported or SlaveId 1 is used in PchLp
+  @retval EFI_INVALID_PARAMETER Slave configuration register address exceed maximum allowed
+  @retval EFI_INVALID_PARAMETER Slave configuration register address is not DWord aligned
+  @retval EFI_ACCESS_DENIED     eSPI Slave write to address range 0 to 0x7FF has been locked
+  @retval EFI_DEVICE_ERROR      Error in SCRS during polling stage of operation
+**/
+EFI_STATUS
+PchEspiSlaveSetConfig (
+  IN  UINT32 SlaveId,
+  IN  UINT32 SlaveAddress,
+  IN  UINT32 InData
+  );
+
+/**
+  Get status from eSPI slave
+
+  @param[in]  SlaveId       eSPI slave ID
+  @param[out] OutData       Configuration data read
+
+  @retval EFI_SUCCESS           Operation succeed
+  @retval EFI_INVALID_PARAMETER Slave ID is not supported or SlaveId 1 is used in PchLp
+  @retval EFI_DEVICE_ERROR      Error in SCRS during polling stage of operation
+**/
+EFI_STATUS
+PchEspiSlaveGetStatus (
+  IN  UINT32 SlaveId,
+  OUT UINT16 *OutData
+  );
+
+/**
+  eSPI slave in-band reset
+
+  @param[in]  SlaveId       eSPI slave ID
+
+  @retval EFI_SUCCESS           Operation succeed
+  @retval EFI_INVALID_PARAMETER Slave ID is not supported or SlaveId 1 is used in PchLp
+  @retval EFI_DEVICE_ERROR      Error in SCRS during polling stage of operation
+**/
+EFI_STATUS
+PchEspiSlaveInBandReset (
+  IN  UINT32 SlaveId
+  );
+
+/**
+  eSPI Slave channel reset helper function
+
+  @param[in]  SlaveId           eSPI slave ID
+  @param[in]  ChannelNumber     Number of channel to reset
+
+  @retval     EFI_SUCCESS       Operation succeeded
+  @retval     EFI_UNSUPPORTED   Slave doesn't support that channel or invalid number specified
+  @retval     EFI_TIMEOUT       Operation has timeouted
+**/
+EFI_STATUS
+PchEspiSlaveChannelReset (
+  IN  UINT8   SlaveId,
+  IN  UINT8   ChannelNumber
+  );
+
+#endif // _ESPI_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/GbeLib.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/GbeLib.h
new file mode 100644
index 0000000000..9d72b9ac7c
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/GbeLib.h
@@ -0,0 +1,63 @@
+/** @file
+  Header file for GbeLib.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _GBE_LIB_H_
+#define _GBE_LIB_H_
+
+/**
+  Check whether GbE region is valid
+  Check SPI region directly since GbE might be disabled in SW.
+
+  @retval TRUE                    Gbe Region is valid
+  @retval FALSE                   Gbe Region is invalid
+**/
+BOOLEAN
+IsGbeRegionValid (
+  VOID
+  );
+
+/**
+  Check whether GBE controller is enabled in the platform.
+
+  @retval TRUE                    GbE is enabled
+  @retval FALSE                   GbE is disabled
+**/
+BOOLEAN
+IsGbePresent (
+  VOID
+  );
+
+/**
+  Checks if Gbe is Enabled or Disabled
+
+  @retval  BOOLEAN    TRUE if device is enabled, FALSE otherwise.
+**/
+BOOLEAN
+IsGbeEnabled (
+  VOID
+  );
+
+/**
+  Returns Gigabit Ethernet PCI Device Number
+
+  @retval  GbE device number
+**/
+UINT8
+GbeDevNumber (
+  VOID
+  );
+
+/**
+  Returns Gigabit Ethernet PCI Function Number
+
+  @retval  GbE function number
+**/
+UINT8
+GbeFuncNumber (
+  VOID
+  );
+
+#endif // _GBE_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/GpioConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/GpioConfig.h
new file mode 100644
index 0000000000..88a21efb32
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/GpioConfig.h
@@ -0,0 +1,342 @@
+/** @file
+  Header file for GpioConfig structure used by GPIO library.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _GPIO_CONFIG_H_
+#define _GPIO_CONFIG_H_
+
+#pragma pack(push, 1)
+
+///
+/// For any GpioPad usage in code use GPIO_PAD type
+///
+typedef UINT32 GPIO_PAD;
+
+///
+/// GpioPad with additional native function information.
+/// This type is used to represent signal muxing alternatives. Platform will provide such value to
+/// identify muxing selection for given signal on a specific SOC.
+/// Please refer to the board layout
+///
+typedef UINT32 GPIO_NATIVE_PAD;
+
+
+///
+/// For any GpioGroup usage in code use GPIO_GROUP type
+///
+typedef UINT32 GPIO_GROUP;
+
+/**
+  GPIO configuration structure used for pin programming.
+  Structure contains fields that can be used to configure pad.
+**/
+typedef struct {
+  /**
+  Pad Mode
+  Pad can be set as GPIO or one of its native functions.
+  When in native mode setting Direction (except Inversion), OutputState,
+  InterruptConfig, Host Software Pad Ownership and OutputStateLock are unnecessary.
+  Refer to definition of GPIO_PAD_MODE.
+  Refer to EDS for each native mode according to the pad.
+  **/
+  UINT32 PadMode            : 5;
+  /**
+  Host Software Pad Ownership
+  Set pad to ACPI mode or GPIO Driver Mode.
+  Refer to definition of GPIO_HOSTSW_OWN.
+  **/
+  UINT32 HostSoftPadOwn     : 2;
+  /**
+  GPIO Direction
+  Can choose between In, In with inversion, Out, both In and Out, both In with inversion and out or disabling both.
+  Refer to definition of GPIO_DIRECTION for supported settings.
+  **/
+  UINT32 Direction           : 6;
+  /**
+  Output State
+  Set Pad output value.
+  Refer to definition of GPIO_OUTPUT_STATE for supported settings.
+  This setting takes place when output is enabled.
+  **/
+  UINT32 OutputState         : 2;
+  /**
+  GPIO Interrupt Configuration
+  Set Pad to cause one of interrupts (IOxAPIC/SCI/SMI/NMI).
+  This setting is applicable only if GPIO is in GpioMode with input enabled.
+  Refer to definition of GPIO_INT_CONFIG for supported settings.
+  **/
+  UINT32 InterruptConfig     : 9;
+  /**
+  GPIO Power Configuration.
+  This setting controls Pad Reset Configuration.
+  Refer to definition of GPIO_RESET_CONFIG for supported settings.
+  **/
+  UINT32 PowerConfig        : 8;
+  /**
+  GPIO Electrical Configuration
+  This setting controls pads termination.
+  Refer to definition of GPIO_ELECTRICAL_CONFIG for supported settings.
+  **/
+  UINT32 ElectricalConfig   : 9;
+  /**
+  GPIO Lock Configuration
+  This setting controls pads lock.
+  Refer to definition of GPIO_LOCK_CONFIG for supported settings.
+  **/
+  UINT32 LockConfig         : 4;
+  /**
+  Additional GPIO configuration
+  Refer to definition of GPIO_OTHER_CONFIG for supported settings.
+  **/
+  UINT32 OtherSettings      : 9;
+
+  UINT32 RsvdBits           : 10;    ///< Reserved bits for future extension
+} GPIO_CONFIG;
+
+
+typedef enum {
+  GpioHardwareDefault        = 0x0    ///< Leave setting unmodified
+} GPIO_HARDWARE_DEFAULT;
+
+/**
+  GPIO Pad Mode
+  Refer to GPIO documentation on native functions available for certain pad.
+  If GPIO is set to one of NativeX modes then following settings are not applicable
+  and can be skipped:
+  - Interrupt related settings
+  - Host Software Ownership
+  - Output/Input enabling/disabling
+  - Output lock
+**/
+typedef enum {
+  GpioPadModeHwDefault  = 0x0,
+  GpioPadModeGpio       = 0x1,
+  GpioPadModeNative1    = 0x3,
+  GpioPadModeNative2    = 0x5,
+  GpioPadModeNative3    = 0x7,
+  GpioPadModeNative4    = 0x9,
+  GpioPadModeNative5    = 0xB,
+  GpioPadModeNative6    = 0xD,
+  GpioPadModeNative7    = 0xF
+} GPIO_PAD_MODE;
+
+/**
+  Host Software Pad Ownership modes
+  This setting affects GPIO interrupt status registers. Depending on chosen ownership
+  some GPIO Interrupt status register get updated and other masked.
+  Please refer to EDS for HOSTSW_OWN register description.
+**/
+typedef enum {
+  GpioHostOwnDefault = 0x0,   ///< Leave ownership value unmodified
+  /**
+  Set HOST ownership to ACPI.
+  Use this setting if pad is not going to be used by GPIO OS driver.
+  If GPIO is configured to generate SCI/SMI/NMI then this setting must be
+  used for interrupts to work
+  **/
+  GpioHostOwnAcpi    = 0x1,
+  /**
+  Set HOST ownership to GPIO Driver mode.
+  Use this setting only if GPIO pad should be controlled by GPIO OS Driver.
+  GPIO OS Driver will be able to control the pad if appropriate entry in
+  ACPI exists (refer to ACPI specification for GpioIo and GpioInt descriptors)
+  **/
+  GpioHostOwnGpio    = 0x3
+} GPIO_HOSTSW_OWN;
+
+///
+/// GPIO Direction
+///
+typedef enum {
+  GpioDirDefault         = 0x0,                ///< Leave pad direction setting unmodified
+  GpioDirInOut           = (0x1 | (0x1 << 3)), ///< Set pad for both output and input
+  GpioDirInInvOut        = (0x1 | (0x3 << 3)), ///< Set pad for both output and input with inversion
+  GpioDirIn              = (0x3 | (0x1 << 3)), ///< Set pad for input only
+  GpioDirInInv           = (0x3 | (0x3 << 3)), ///< Set pad for input with inversion
+  GpioDirOut             = 0x5,                ///< Set pad for output only
+  GpioDirNone            = 0x7                 ///< Disable both output and input
+} GPIO_DIRECTION;
+
+/**
+  GPIO Output State
+  This field is relevant only if output is enabled
+**/
+typedef enum {
+  GpioOutDefault         = 0x0,  ///< Leave output value unmodified
+  GpioOutLow             = 0x1,  ///< Set output to low
+  GpioOutHigh            = 0x3   ///< Set output to high
+} GPIO_OUTPUT_STATE;
+
+/**
+  GPIO interrupt configuration
+  This setting is applicable only if pad is in GPIO mode and has input enabled.
+  GPIO_INT_CONFIG allows to choose which interrupt is generated (IOxAPIC/SCI/SMI/NMI)
+  and how it is triggered (edge or level). Refer to PADCFG_DW0 register description in
+  EDS for details on this settings.
+  Field from GpioIntNmi to GpioIntApic can be OR'ed with GpioIntLevel to GpioIntBothEdge
+  to describe an interrupt e.g. GpioIntApic | GpioIntLevel
+  If GPIO is set to cause an SCI then also GPI_GPE_EN is enabled for this pad.
+  If GPIO is set to cause an NMI then also GPI_NMI_EN is enabled for this pad.
+  Not all GPIO are capable of generating an SMI or NMI interrupt.
+  When routing GPIO to cause an IOxAPIC interrupt care must be taken, as this
+  interrupt cannot be shared and its IRQn number is not configurable.
+  Refer to EDS for GPIO pads IRQ numbers (PADCFG_DW1.IntSel)
+  If GPIO is under GPIO OS driver control and appropriate ACPI GpioInt descriptor
+  exist then use only trigger type setting (from GpioIntLevel to GpioIntBothEdge).
+  This type of GPIO Driver interrupt doesn't have any additional routing setting
+  required to be set by BIOS. Interrupt is handled by GPIO OS Driver.
+**/
+
+typedef enum {
+  GpioIntDefault           = 0x0,  ///< Leave value of interrupt routing unmodified
+  GpioIntDis               = 0x1,  ///< Disable IOxAPIC/SCI/SMI/NMI interrupt generation
+  GpioIntNmi               = 0x3,  ///< Enable NMI interrupt only
+  GpioIntSmi               = 0x5,  ///< Enable SMI interrupt only
+  GpioIntSci               = 0x9,  ///< Enable SCI interrupt only
+  GpioIntApic              = 0x11, ///< Enable IOxAPIC interrupt only
+  GpioIntLevel       = (0x1 << 5), ///< Set interrupt as level triggered
+  GpioIntEdge        = (0x3 << 5), ///< Set interrupt as edge triggered (type of edge depends on input inversion)
+  GpioIntLvlEdgDis   = (0x5 << 5), ///< Disable interrupt trigger
+  GpioIntBothEdge    = (0x7 << 5)  ///< Set interrupt as both edge triggered
+} GPIO_INT_CONFIG;
+
+#define B_GPIO_INT_CONFIG_INT_SOURCE_MASK  0x1F ///< Mask for GPIO_INT_CONFIG for interrupt source
+#define B_GPIO_INT_CONFIG_INT_TYPE_MASK    0xE0 ///< Mask for GPIO_INT_CONFIG for interrupt type
+
+/**
+  GPIO Power Configuration
+  GPIO_RESET_CONFIG allows to set GPIO Reset type (PADCFG_DW0.PadRstCfg) which will
+  be used to reset certain GPIO settings.
+  Refer to EDS for settings that are controllable by PadRstCfg.
+**/
+typedef enum {
+  GpioResetDefault   = 0x00,        ///< Leave value of pad reset unmodified
+  /**
+  Resume Reset (RSMRST)
+    GPP: PadRstCfg = 00b = "Powergood"
+    GPD: PadRstCfg = 11b = "Resume Reset"
+  Pad setting will reset on:
+  - DeepSx transition
+  - G3
+  Pad settings will not reset on:
+  - S3/S4/S5 transition
+  - Warm/Cold/Global reset
+  **/
+  GpioResumeReset      = 0x01,
+  /**
+  Host Deep Reset
+    PadRstCfg = 01b = "Deep GPIO Reset"
+  Pad settings will reset on:
+  - Warm/Cold/Global reset
+  - DeepSx transition
+  - G3
+  Pad settings will not reset on:
+  - S3/S4/S5 transition
+  **/
+  GpioHostDeepReset    = 0x03,
+  /**
+  Platform Reset (PLTRST)
+    PadRstCfg = 10b = "GPIO Reset"
+  Pad settings will reset on:
+  - S3/S4/S5 transition
+  - Warm/Cold/Global reset
+  - DeepSx transition
+  - G3
+  **/
+  GpioPlatformReset    = 0x05,
+  /**
+  Deep Sleep Well Reset (DSW_PWROK)
+    GPP: not applicable
+    GPD: PadRstCfg = 00b = "Powergood"
+  Pad settings will reset on:
+  - G3
+  Pad settings will not reset on:
+  - S3/S4/S5 transition
+  - Warm/Cold/Global reset
+  - DeepSx transition
+  **/
+  GpioDswReset         = 0x07
+} GPIO_RESET_CONFIG;
+
+/**
+  GPIO Electrical Configuration
+  Configuration options for GPIO termination setting
+**/
+typedef enum {
+  GpioTermDefault          = 0x0,  ///< Leave termination setting unmodified
+  GpioTermNone             = 0x1,  ///< none
+  GpioTermWpd5K            = 0x5,  ///< 5kOhm weak pull-down
+  GpioTermWpd20K           = 0x9,  ///< 20kOhm weak pull-down
+  GpioTermWpu1K            = 0x13, ///< 1kOhm weak pull-up
+  GpioTermWpu2K            = 0x17, ///< 2kOhm weak pull-up
+  GpioTermWpu5K            = 0x15, ///< 5kOhm weak pull-up
+  GpioTermWpu20K           = 0x19, ///< 20kOhm weak pull-up
+  GpioTermWpu1K2K          = 0x1B, ///< 1kOhm & 2kOhm weak pull-up
+  /**
+  Native function controls pads termination
+  This setting is applicable only to some native modes.
+  Please check EDS to determine which native functionality
+  can control pads termination
+  **/
+  GpioTermNative           = 0x1F
+} GPIO_ELECTRICAL_CONFIG;
+
+#define B_GPIO_ELECTRICAL_CONFIG_TERMINATION_MASK    0x1F   ///< Mask for GPIO_ELECTRICAL_CONFIG for termination value
+
+/**
+  GPIO LockConfiguration
+  Set GPIO configuration lock and output state lock.
+  GpioPadConfigUnlock/Lock and GpioOutputStateUnlock can be OR'ed.
+  By default GPIO pads will be locked unless GPIO lib is explicitly
+  informed that certain pad is to be left unlocked.
+  Lock settings reset is in Powergood domain. Care must be taken when using this setting
+  as fields it locks may be reset by a different signal and can be controlled
+  by what is in GPIO_RESET_CONFIG (PADCFG_DW0.PadRstCfg). GPIO library provides
+  functions which allow to unlock a GPIO pad. If possible each GPIO lib function will try to unlock
+  an already locked pad upon request for reconfiguration
+**/
+typedef enum {
+  /**
+  Perform default action
+   - if pad is an GPO, lock configuration but leave output unlocked
+   - if pad is an GPI, lock everything
+   - if pad is in native, lock everything
+**/
+  GpioLockDefault         = 0x0,
+  GpioPadConfigUnlock     = 0x3,  ///< Leave Pad configuration unlocked
+  GpioPadConfigLock       = 0x1,  ///< Lock Pad configuration
+  GpioOutputStateUnlock   = 0xC,  ///< Leave Pad output control unlocked
+  GpioPadUnlock           = 0xF,  ///< Leave both Pad configuration and output control unlocked
+  GpioPadLock             = 0x5,  ///< Lock both Pad configuration and output control
+  /**
+    Below statuses are used for
+    return from GpioGetPadConfig function
+  **/
+  GpioLockTxLockCfgUnLock = 0x7,  ///< Tx State locked, Pad Configuration unlocked
+  GpioLockTxUnLockCfgLock = 0xD   ///< Tx State unlocked, Pad Configuration locked
+} GPIO_LOCK_CONFIG;
+
+#define B_GPIO_LOCK_CONFIG_PAD_CONF_LOCK_MASK  0x3  ///< Mask for GPIO_LOCK_CONFIG for Pad Configuration Lock
+#define B_GPIO_LOCK_CONFIG_OUTPUT_LOCK_MASK    0xC  ///< Mask for GPIO_LOCK_CONFIG for Pad Output Lock
+
+/**
+  Other GPIO Configuration
+  GPIO_OTHER_CONFIG is used for less often settings and for future extensions
+  Supported settings:
+   - RX raw override to '1' - allows to override input value to '1'
+      This setting is applicable only if in input mode (both in GPIO and native usage).
+      The override takes place at the internal pad state directly from buffer and before the RXINV.
+**/
+typedef enum {
+  GpioRxRaw1Default           = 0x0,  ///< Use default input override value
+  GpioRxRaw1Dis               = 0x1,  ///< Don't override input
+  GpioRxRaw1En                = 0x3   ///< Override input to '1'
+} GPIO_OTHER_CONFIG;
+
+#define B_GPIO_OTHER_CONFIG_RXRAW_MASK           0x3   ///< Mask for GPIO_OTHER_CONFIG for RxRaw1 setting
+
+#pragma pack(pop)
+
+#endif //_GPIO_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/GpioLib.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/GpioLib.h
new file mode 100644
index 0000000000..5b3cf502a0
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/GpioLib.h
@@ -0,0 +1,720 @@
+/** @file
+  Header file for GpioLib.
+  All function in this library is available for PEI, DXE, and SMM
+
+  @note: When GPIO pads are owned by ME Firmware, BIOS/host should not
+         attempt to access these GPIO Pads registers, registers value
+         returned in this case will be 0xFF.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _GPIO_LIB_H_
+#define _GPIO_LIB_H_
+
+#include <Library/GpioConfig.h>
+
+#define GPIO_NAME_LENGTH_MAX  32
+
+typedef struct {
+  GPIO_PAD           GpioPad;
+  GPIO_CONFIG        GpioConfig;
+} GPIO_INIT_CONFIG;
+
+/**
+  This procedure will initialize multiple GPIO pins. Use GPIO_INIT_CONFIG structure.
+  Structure contains fields that can be used to configure each pad.
+  Pad not configured using GPIO_INIT_CONFIG will be left with hardware default values.
+  Separate fields could be set to hardware default if it does not matter, except
+  GpioPad and PadMode.
+  Function will work in most efficient way if pads which belong to the same group are
+  placed in adjacent records of the table.
+  Although function can enable pads for Native mode, such programming is done
+  by reference code when enabling related silicon feature.
+
+  @param[in] NumberofItem               Number of GPIO pads to be updated
+  @param[in] GpioInitTableAddress       GPIO initialization table
+
+  @retval EFI_SUCCESS                   The function completed successfully
+  @retval EFI_INVALID_PARAMETER         Invalid group or pad number
+**/
+EFI_STATUS
+GpioConfigurePads (
+  IN UINT32                    NumberOfItems,
+  IN GPIO_INIT_CONFIG          *GpioInitTableAddress
+  );
+
+//
+// Functions for setting/getting multiple GpioPad settings
+//
+
+/**
+  This procedure will read multiple GPIO settings
+
+  @param[in]  GpioPad                   GPIO Pad
+  @param[out] GpioData                  GPIO data structure
+
+  @retval EFI_SUCCESS                   The function completed successfully
+  @retval EFI_INVALID_PARAMETER         Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetPadConfig (
+  IN  GPIO_PAD               GpioPad,
+  OUT GPIO_CONFIG            *GpioData
+  );
+
+/**
+  This procedure will configure multiple GPIO settings
+
+  @param[in] GpioPad                    GPIO Pad
+  @param[in] GpioData                   GPIO data structure
+
+  @retval EFI_SUCCESS                   The function completed successfully
+  @retval EFI_INVALID_PARAMETER         Invalid GpioPad
+**/
+EFI_STATUS
+GpioSetPadConfig (
+  IN GPIO_PAD                  GpioPad,
+  IN GPIO_CONFIG               *GpioData
+  );
+
+//
+// Functions for setting/getting single GpioPad properties
+//
+
+/**
+  This procedure will set GPIO output level
+
+  @param[in] GpioPad              GPIO pad
+  @param[in] Value                Output value
+                                  0: OutputLow, 1: OutputHigh
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioSetOutputValue (
+  IN GPIO_PAD                  GpioPad,
+  IN UINT32                    Value
+  );
+
+/**
+  This procedure will get GPIO output level
+
+  @param[in]  GpioPad             GPIO pad
+  @param[out] OutputVal           GPIO Output value
+                                  0: OutputLow, 1: OutputHigh
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetOutputValue (
+  IN GPIO_PAD                  GpioPad,
+  OUT UINT32                   *OutputVal
+  );
+
+/**
+  This procedure will get GPIO input level
+
+  @param[in]  GpioPad             GPIO pad
+  @param[out] InputVal            GPIO Input value
+                                  0: InputLow, 1: InputHigh
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetInputValue (
+  IN GPIO_PAD                  GpioPad,
+  OUT UINT32                   *InputVal
+  );
+
+/**
+  This procedure will get GPIO IOxAPIC interrupt number
+
+  @param[in]  GpioPad             GPIO pad
+  @param[out] IrqNum              IRQ number
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetPadIoApicIrqNumber (
+  IN GPIO_PAD                  GpioPad,
+  OUT UINT32                   *IrqNum
+  );
+
+/**
+  This procedure will configure GPIO input inversion
+
+  @param[in] GpioPad              GPIO pad
+  @param[in] Value                Value for GPIO input inversion
+                                  0: No input inversion, 1: Invert input
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioSetInputInversion (
+  IN GPIO_PAD                  GpioPad,
+  IN UINT32                    Value
+  );
+
+/**
+  This procedure will get GPIO pad input inversion value
+
+  @param[in] GpioPad              GPIO pad
+  @param[out] InvertState         GPIO inversion state
+                                  0: No input inversion, 1: Inverted input
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetInputInversion (
+  IN GPIO_PAD                  GpioPad,
+  OUT UINT32                   *InvertState
+  );
+
+/**
+  This procedure will set GPIO interrupt settings
+
+  @param[in] GpioPad              GPIO pad
+  @param[in] Value                Value of Level/Edge
+                                  use GPIO_INT_CONFIG as argument
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioSetPadInterruptConfig (
+  IN GPIO_PAD                 GpioPad,
+  IN GPIO_INT_CONFIG          Value
+  );
+
+/**
+  This procedure will set GPIO electrical settings
+
+  @param[in] GpioPad              GPIO pad
+  @param[in] Value                Value of termination
+                                  use GPIO_ELECTRICAL_CONFIG as argument
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioSetPadElectricalConfig (
+  IN GPIO_PAD                  GpioPad,
+  IN GPIO_ELECTRICAL_CONFIG    Value
+  );
+
+/**
+  This procedure will set GPIO Reset settings
+
+  @param[in] GpioPad              GPIO pad
+  @param[in] Value                Value for Pad Reset Configuration
+                                  use GPIO_RESET_CONFIG as argument
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioSetPadResetConfig (
+  IN GPIO_PAD                  GpioPad,
+  IN GPIO_RESET_CONFIG         Value
+  );
+
+/**
+  This procedure will get GPIO Reset settings
+
+  @param[in] GpioPad              GPIO pad
+  @param[in] Value                Value of Pad Reset Configuration
+                                  based on GPIO_RESET_CONFIG
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetPadResetConfig (
+  IN GPIO_PAD                  GpioPad,
+  IN GPIO_RESET_CONFIG         *Value
+  );
+
+/**
+  This procedure will get Gpio Pad Host Software Ownership
+
+  @param[in] GpioPad              GPIO pad
+  @param[out] PadHostSwOwn        Value of Host Software Pad Owner
+                                  0: ACPI Mode, 1: GPIO Driver mode
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetHostSwOwnershipForPad (
+  IN GPIO_PAD                 GpioPad,
+  OUT UINT32                  *PadHostSwOwn
+  );
+
+/**
+  This procedure will set Gpio Pad Host Software Ownership
+
+  @param[in] GpioPad              GPIO pad
+  @param[in]  PadHostSwOwn        Pad Host Software Owner
+                                  0: ACPI Mode, 1: GPIO Driver mode
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioSetHostSwOwnershipForPad (
+  IN GPIO_PAD                  GpioPad,
+  IN UINT32                    PadHostSwOwn
+  );
+
+///
+/// Possible values of Pad Ownership
+/// If Pad is not under Host ownership then GPIO registers
+/// are not accessible by host (e.g. BIOS) and reading them
+/// will return 0xFFs.
+///
+typedef enum {
+  GpioPadOwnHost = 0x0,
+  GpioPadOwnCsme = 0x1,
+  GpioPadOwnIsh  = 0x2,
+} GPIO_PAD_OWN;
+
+/**
+  This procedure will get Gpio Pad Ownership
+
+  @param[in] GpioPad              GPIO pad
+  @param[out] PadOwnVal           Value of Pad Ownership
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetPadOwnership (
+  IN  GPIO_PAD                GpioPad,
+  OUT GPIO_PAD_OWN            *PadOwnVal
+  );
+
+/**
+  This procedure will check state of Pad Config Lock for pads within one group
+
+  @param[in]  Group               GPIO group
+  @param[in]  DwNum               PadCfgLock register number for current group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[out] PadCfgLockRegVal    Value of PadCfgLock register
+                                  Bit position - PadNumber
+                                  Bit value - 0: NotLocked, 1: Locked
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or DwNum parameter number
+**/
+EFI_STATUS
+GpioGetPadCfgLockForGroupDw (
+  IN  GPIO_GROUP                  Group,
+  IN  UINT32                      DwNum,
+  OUT UINT32                      *PadCfgLockRegVal
+  );
+
+/**
+  This procedure will check state of Pad Config Lock for selected pad
+
+  @param[in]  GpioPad             GPIO pad
+  @param[out] PadCfgLock          PadCfgLock for selected pad
+                                  0: NotLocked, 1: Locked
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetPadCfgLock (
+  IN GPIO_PAD                   GpioPad,
+  OUT UINT32                    *PadCfgLock
+  );
+
+/**
+  This procedure will check state of Pad Config Tx Lock for pads within one group
+
+  @param[in]  Group               GPIO group
+  @param[in]  DwNum               PadCfgLockTx register number for current group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[out] PadCfgLockTxRegVal  Value of PadCfgLockTx register
+                                  Bit position - PadNumber
+                                  Bit value - 0: NotLockedTx, 1: LockedTx
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or DwNum parameter number
+**/
+EFI_STATUS
+GpioGetPadCfgLockTxForGroupDw (
+  IN  GPIO_GROUP                  Group,
+  IN  UINT32                      DwNum,
+  OUT UINT32                      *PadCfgLockTxRegVal
+  );
+
+/**
+  This procedure will check state of Pad Config Tx Lock for selected pad
+
+  @param[in]  GpioPad             GPIO pad
+  @param[out] PadCfgLock          PadCfgLockTx for selected pad
+                                  0: NotLockedTx, 1: LockedTx
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetPadCfgLockTx (
+  IN GPIO_PAD                   GpioPad,
+  OUT UINT32                    *PadCfgLockTx
+  );
+
+/**
+  This procedure will clear PadCfgLock for selected pads within one group.
+  Unlocking a pad will cause an SMI (if enabled)
+
+  @param[in]  Group               GPIO group
+  @param[in]  DwNum               PadCfgLock register number for current group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in]  PadsToUnlock        Bitmask for pads which are going to be unlocked,
+                                  Bit position - PadNumber
+                                  Bit value - 0: DoNotUnlock, 1: Unlock
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioUnlockPadCfgForGroupDw (
+  IN GPIO_GROUP                Group,
+  IN UINT32                    DwNum,
+  IN UINT32                    PadsToUnlock
+  );
+
+/**
+  This procedure will clear PadCfgLock for selected pad.
+  Unlocking a pad will cause an SMI (if enabled)
+
+  @param[in] GpioPad              GPIO pad
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioUnlockPadCfg (
+  IN GPIO_PAD                   GpioPad
+  );
+
+/**
+  This procedure will set PadCfgLock for selected pads within one group
+
+  @param[in]  Group               GPIO group
+  @param[in]  DwNum               PadCfgLock register number for current group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in]  PadsToLock          Bitmask for pads which are going to be locked,
+                                  Bit position - PadNumber
+                                  Bit value - 0: DoNotLock, 1: Lock
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or DwNum parameter number
+**/
+EFI_STATUS
+GpioLockPadCfgForGroupDw (
+  IN GPIO_GROUP                   Group,
+  IN UINT32                       DwNum,
+  IN UINT32                       PadsToLock
+  );
+
+/**
+  This procedure will set PadCfgLock for selected pad
+
+  @param[in] GpioPad              GPIO pad
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioLockPadCfg (
+  IN GPIO_PAD                   GpioPad
+  );
+
+/**
+  This procedure will clear PadCfgLockTx for selected pads within one group.
+  Unlocking a pad will cause an SMI (if enabled)
+
+  @param[in]  Group               GPIO group
+  @param[in]  DwNum               PadCfgLockTx register number for current group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in]  PadsToUnlockTx      Bitmask for pads which are going to be unlocked,
+                                  Bit position - PadNumber
+                                  Bit value - 0: DoNotUnLockTx, 1: LockTx
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioUnlockPadCfgTxForGroupDw (
+  IN GPIO_GROUP                Group,
+  IN UINT32                    DwNum,
+  IN UINT32                    PadsToUnlockTx
+  );
+
+/**
+  This procedure will clear PadCfgLockTx for selected pad.
+  Unlocking a pad will cause an SMI (if enabled)
+
+  @param[in] GpioPad              GPIO pad
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioUnlockPadCfgTx (
+  IN GPIO_PAD                   GpioPad
+  );
+
+/**
+  This procedure will set PadCfgLockTx for selected pads within one group
+
+  @param[in]  Group               GPIO group
+  @param[in]  DwNum               PadCfgLock register number for current group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in]  PadsToLockTx        Bitmask for pads which are going to be locked,
+                                  Bit position - PadNumber
+                                  Bit value - 0: DoNotLockTx, 1: LockTx
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or DwNum parameter number
+**/
+EFI_STATUS
+GpioLockPadCfgTxForGroupDw (
+  IN GPIO_GROUP                   Group,
+  IN UINT32                       DwNum,
+  IN UINT32                       PadsToLockTx
+  );
+
+/**
+  This procedure will set PadCfgLockTx for selected pad
+
+  @param[in] GpioPad              GPIO pad
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioLockPadCfgTx (
+  IN GPIO_PAD                   GpioPad
+  );
+
+/**
+  This procedure will get Group to GPE mapping.
+  It will assume that only first 32 pads can be mapped to GPE.
+  To handle cases where groups have more than 32 pads and higher part of group
+  can be mapped please refer to GpioGetGroupDwToGpeDwX()
+
+  @param[out] GroupToGpeDw0       GPIO group to be mapped to GPE_DW0
+  @param[out] GroupToGpeDw1       GPIO group to be mapped to GPE_DW1
+  @param[out] GroupToGpeDw2       GPIO group to be mapped to GPE_DW2
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioGetGroupToGpeDwX (
+  IN GPIO_GROUP               *GroupToGpeDw0,
+  IN GPIO_GROUP               *GroupToGpeDw1,
+  IN GPIO_GROUP               *GroupToGpeDw2
+  );
+
+/**
+  This procedure will get Group to GPE mapping. If group has more than 32 bits
+  it is possible to map only single DW of pins (e.g. 0-31, 32-63) because
+  ACPI GPE_DWx register is 32 bits large.
+
+  @param[out]  GroupToGpeDw0       GPIO group mapped to GPE_DW0
+  @param[out]  GroupDwForGpeDw0    DW of pins mapped to GPE_DW0
+  @param[out]  GroupToGpeDw1       GPIO group mapped to GPE_DW1
+  @param[out]  GroupDwForGpeDw1    DW of pins mapped to GPE_DW1
+  @param[out]  GroupToGpeDw2       GPIO group mapped to GPE_DW2
+  @param[out]  GroupDwForGpeDw2    DW of pins mapped to GPE_DW2
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioGetGroupDwToGpeDwX (
+  OUT GPIO_GROUP                *GroupToGpeDw0,
+  OUT UINT32                    *GroupDwForGpeDw0,
+  OUT GPIO_GROUP                *GroupToGpeDw1,
+  OUT UINT32                    *GroupDwForGpeDw1,
+  OUT GPIO_GROUP                *GroupToGpeDw2,
+  OUT UINT32                    *GroupDwForGpeDw2
+  );
+
+/**
+  This procedure will get GPE number for provided GpioPad.
+  PCH allows to configure mapping between GPIO groups and related GPE (GpioSetGroupToGpeDwX())
+  what results in the fact that certain Pad can cause different General Purpose Event. Only three
+  GPIO groups can be mapped to cause unique GPE (1-tier), all others groups will be under one common
+  event (GPE_111 for 2-tier).
+
+  1-tier:
+  Returned GpeNumber is in range <0,95>. GpioGetGpeNumber() can be used
+  to determine what _LXX ACPI method would be called on event on selected GPIO pad
+
+  2-tier:
+  Returned GpeNumber is 0x6F (111). All GPIO pads which are not mapped to 1-tier GPE
+  will be under one master GPE_111 which is linked to _L6F ACPI method. If it is needed to determine
+  what Pad from 2-tier has caused the event, _L6F method should check GPI_GPE_STS and GPI_GPE_EN
+  registers for all GPIO groups not mapped to 1-tier GPE.
+
+  @param[in]  GpioPad             GPIO pad
+  @param[out] GpeNumber           GPE number
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetGpeNumber (
+  IN GPIO_PAD                   GpioPad,
+  OUT UINT32                    *GpeNumber
+  );
+
+/**
+  This procedure is used to clear SMI STS for a specified Pad
+
+  @param[in]  GpioPad             GPIO pad
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioClearGpiSmiSts (
+  IN GPIO_PAD                   GpioPad
+  );
+
+/**
+  This procedure is used by Smi Dispatcher and will clear
+  all GPI SMI Status bits
+
+  @retval EFI_SUCCESS             The function completed successfully
+**/
+EFI_STATUS
+GpioClearAllGpiSmiSts (
+  VOID
+  );
+
+/**
+  This procedure is used to disable all GPI SMI
+
+  @retval EFI_SUCCESS             The function completed successfully
+**/
+EFI_STATUS
+GpioDisableAllGpiSmi (
+  VOID
+  );
+
+/**
+  This procedure is used to register GPI SMI dispatch function.
+
+  @param[in]  GpioPad             GPIO pad
+  @param[out] GpiNum              GPI number
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetGpiSmiNum (
+  IN GPIO_PAD          GpioPad,
+  OUT UINTN            *GpiNum
+  );
+
+/**
+  This procedure is used to check GPIO inputs belongs to 2 tier or 1 tier architecture
+
+  @param[in]  GpioPad             GPIO pad
+
+  @retval     Data                0 means 1-tier, 1 means 2-tier
+**/
+BOOLEAN
+GpioCheckFor2Tier (
+  IN GPIO_PAD                  GpioPad
+  );
+
+/**
+  This procedure is used to clear GPE STS for a specified GpioPad
+
+  @param[in]  GpioPad             GPIO pad
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioClearGpiGpeSts (
+  IN GPIO_PAD                  GpioPad
+  );
+
+/**
+  This procedure is used to read GPE STS for a specified Pad
+
+  @param[in]  GpioPad             GPIO pad
+  @param[out] GpeSts              Gpe status for given pad
+                                  The GpeSts is true if the status register is set for given Pad number
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetGpiGpeSts (
+  IN GPIO_PAD                  GpioPad,
+  OUT BOOLEAN                  *GpeSts
+  );
+
+/**
+  This procedure is used to get SMI STS for a specified Pad
+
+  @param[in]  GpioPad             GPIO pad
+  @param[out] SmiSts              Smi status for given pad
+                                  The SmiSts is true if the status register is set for given Pad number
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetGpiSmiSts (
+  IN GPIO_PAD                   GpioPad,
+  OUT BOOLEAN                   *SmiSts
+  );
+
+/**
+  Generates GPIO name from GpioPad
+
+  @param[in]  GpioPad             GpioPad
+  @param[out] GpioNameBuffer      Caller allocated buffer for GPIO name of GPIO_NAME_LENGTH_MAX size
+  @param[in]  GpioNameBufferSize  Size of the buffer
+
+  @retval CHAR8*  Pointer to the GPIO name
+**/
+CHAR8*
+GpioGetPadName (
+  IN  GPIO_PAD  GpioPad,
+  OUT CHAR8*    GpioNameBuffer,
+  IN  UINT32    GpioNameBufferSize
+  );
+
+/**
+  Generates GPIO group name from GroupIndex
+
+  @param[in] GroupIndex  Gpio GroupIndex
+
+  @retval CHAR8*  Pointer to the GPIO group name
+**/
+CONST
+CHAR8*
+GpioGetGroupName (
+  IN UINT32  GroupIndex
+  );
+
+#endif // _GPIO_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/GpioNativeLib.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/GpioNativeLib.h
new file mode 100644
index 0000000000..b09600dd30
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/GpioNativeLib.h
@@ -0,0 +1,149 @@
+/** @file
+  Header file for GpioLib for native and Si specific usage.
+  All function in this library is available for PEI, DXE, and SMM,
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _GPIO_NATIVE_LIB_H_
+#define _GPIO_NATIVE_LIB_H_
+
+#include <Library/GpioConfig.h>
+
+/**
+  This procedure will get number of pads for certain GPIO group
+
+  @param[in] Group            GPIO group number
+
+  @retval Value               Pad number for group
+                              If illegal group number then return 0
+**/
+UINT32
+GpioGetPadPerGroup (
+  IN GPIO_GROUP        Group
+  );
+
+/**
+  This procedure will get number of groups
+
+  @param[in] none
+
+  @retval Value               Group number
+**/
+UINT32
+GpioGetNumberOfGroups (
+  VOID
+  );
+/**
+  This procedure will get lowest group
+
+  @param[in] none
+
+  @retval Value               Lowest Group
+**/
+GPIO_GROUP
+GpioGetLowestGroup (
+  VOID
+  );
+
+/**
+  This procedure will get highest group
+
+  @param[in] none
+
+  @retval Value               Highest Group
+**/
+GPIO_GROUP
+GpioGetHighestGroup (
+  VOID
+  );
+
+/**
+  This procedure will get group
+
+  @param[in] GpioPad          Gpio Pad
+
+  @retval Value               Group
+**/
+GPIO_GROUP
+GpioGetGroupFromGpioPad (
+  IN GPIO_PAD        GpioPad
+  );
+
+/**
+  This procedure will get group index (0 based) from GpioPad
+
+  @param[in] GpioPad          Gpio Pad
+
+  @retval Value               Group Index
+**/
+UINT32
+GpioGetGroupIndexFromGpioPad (
+  IN GPIO_PAD        GpioPad
+  );
+
+/**
+  This procedure will get group index (0 based) from group
+
+  @param[in] GpioGroup        Gpio Group
+
+  @retval Value               Group Index
+**/
+UINT32
+GpioGetGroupIndexFromGroup (
+  IN GPIO_GROUP        GpioGroup
+  );
+
+/**
+  This procedure will get group from group index (0 based)
+
+  @param[in] GroupIndex        Group Index
+
+  @retval GpioGroup            Gpio Group
+**/
+GPIO_GROUP
+GpioGetGroupFromGroupIndex (
+  IN UINT32        GroupIndex
+  );
+
+/**
+  This procedure will get pad number (0 based) from Gpio Pad
+
+  @param[in] GpioPad          Gpio Pad
+
+  @retval Value               Pad Number
+**/
+UINT32
+GpioGetPadNumberFromGpioPad (
+  IN GPIO_PAD        GpioPad
+  );
+
+/**
+  This procedure will return GpioPad from Group and PadNumber
+
+  @param[in] Group              GPIO group
+  @param[in] PadNumber          GPIO PadNumber
+
+  @retval GpioPad               GpioPad
+**/
+GPIO_PAD
+GpioGetGpioPadFromGroupAndPadNumber (
+  IN GPIO_GROUP      Group,
+  IN UINT32          PadNumber
+  );
+
+/**
+  This procedure will return GpioPad from GroupIndex and PadNumber
+
+  @param[in] GroupIndex         GPIO GroupIndex
+  @param[in] PadNumber          GPIO PadNumber
+
+  @retval GpioPad               GpioPad
+**/
+GPIO_PAD
+GpioGetGpioPadFromGroupIndexAndPadNumber (
+  IN UINT32          GroupIndex,
+  IN UINT32          PadNumber
+  );
+
+#endif // _GPIO_NATIVE_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/MmPciLib.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/MmPciLib.h
new file mode 100644
index 0000000000..a53887ffcb
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/MmPciLib.h
@@ -0,0 +1,27 @@
+/** @file
+  Get Pci Express address library implementation.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _MM_PCI_LIB_H_
+#define _MM_PCI_LIB_H_
+
+/**
+  This procedure will get PCIE address
+
+  @param[in] Bus                  Pci Bus Number
+  @param[in] Device               Pci Device Number
+  @param[in] Function             Pci Function Number
+
+  @retval PCIE address
+**/
+UINTN
+EFIAPI
+MmPciBase (
+  IN UINT32                       Bus,
+  IN UINT32                       Device,
+  IN UINT32                       Function
+);
+
+#endif // _PEI_DXE_SMM_MM_PCI_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/PchPcieRpLib.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/PchPcieRpLib.h
new file mode 100644
index 0000000000..3c46029b7f
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/PchPcieRpLib.h
@@ -0,0 +1,123 @@
+/** @file
+  Header file for PchPcieRpLib.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_PCIERP_LIB_H_
+#define _PCH_PCIERP_LIB_H_
+
+#include <Library/PchPcrLib.h>
+
+/**
+  PCIe controller bifurcation configuration.
+**/
+typedef enum {
+  PcieBifurcationDefault = 0,
+  PcieBifurcation4x1,
+  PcieBifurcation1x2_2x1,
+  PcieBifurcation2x2,
+  PcieBifurcation1x4,
+  PcieBifurcation4x2,
+  PcieBifurcation1x4_2x2,
+  PcieBifurcation2x2_1x4,
+  PcieBifurcation2x4,
+  PcieBifurcation1x8,
+  PcieBifurcationUnknown,
+  PcieBifurcationMax
+} PCIE_BIFURCATION_CONFIG;
+
+/**
+  This function returns PID according to PCIe controller index
+
+  @param[in] ControllerIndex     PCIe controller index
+
+  @retval PCH_SBI_PID    Returns PID for SBI Access
+**/
+PCH_SBI_PID
+PchGetPcieControllerSbiPid (
+  IN UINT32  ControllerIndex
+  );
+
+/**
+  This function returns PID according to Root Port Number
+
+  @param[in] RpIndex     Root Port Index (0-based)
+
+  @retval PCH_SBI_PID    Returns PID for SBI Access
+**/
+PCH_SBI_PID
+GetRpSbiPid (
+  IN UINTN  RpIndex
+  );
+
+/**
+  Get Pch Pcie Root Port Device and Function Number by Root Port physical Number
+
+  @param[in]  RpNumber            Root port physical number. (0-based)
+  @param[out] RpDev               Return corresponding root port device number.
+  @param[out] RpFun               Return corresponding root port function number.
+
+  @retval EFI_SUCCESS
+**/
+EFI_STATUS
+EFIAPI
+GetPchPcieRpDevFun (
+  IN  UINTN   RpNumber,
+  OUT UINTN   *RpDev,
+  OUT UINTN   *RpFun
+  );
+
+/**
+  Get Root Port physical Number by Pch Pcie Root Port Device and Function Number
+
+  @param[in]  RpDev                 Root port device number.
+  @param[in]  RpFun                 Root port function number.
+  @param[out] RpNumber              Return corresponding physical Root Port index (0-based)
+
+  @retval     EFI_SUCCESS           Physical root port is retrieved
+  @retval     EFI_INVALID_PARAMETER RpDev and/or RpFun are invalid
+  @retval     EFI_UNSUPPORTED       Root port device and function is not assigned to any physical root port
+**/
+EFI_STATUS
+EFIAPI
+GetPchPcieRpNumber (
+  IN  UINTN   RpDev,
+  IN  UINTN   RpFun,
+  OUT UINTN   *RpNumber
+  );
+
+/**
+  Gets pci segment base address of PCIe root port.
+
+  @param RpIndex    Root Port Index (0 based)
+  @return PCIe port base address.
+**/
+UINT64
+PchPcieBase (
+  IN  UINT32   RpIndex
+  );
+
+/**
+  Determines whether L0s is supported on current stepping.
+
+  @return TRUE if L0s is supported, FALSE otherwise
+**/
+BOOLEAN
+PchIsPcieL0sSupported (
+  VOID
+  );
+
+/**
+  Some early PCH steppings require Native ASPM to be disabled due to hardware issues:
+   - RxL0s exit causes recovery
+   - Disabling PCIe L0s capability disables L1
+  Use this function to determine affected steppings.
+
+  @return TRUE if Native ASPM is supported, FALSE otherwise
+**/
+BOOLEAN
+PchIsPcieNativeAspmSupported (
+  VOID
+  );
+#endif // _PCH_PCIERP_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/PchPcrLib.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/PchPcrLib.h
new file mode 100644
index 0000000000..f46c3da0e1
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/PchPcrLib.h
@@ -0,0 +1,256 @@
+/** @file
+  Header file for PchPcrLib.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_PCR_LIB_H_
+#define _PCH_PCR_LIB_H_
+
+#include <PchReservedResources.h>
+
+/**
+  Definition for PCR address
+  The PCR address is used to the PCR MMIO programming
+
+  SBREG_BAR_20BITADDRESS is configured by SoC
+
+  SBREG_BAR_20BITADDRESS=1, the format has included 16b addressing.
+  +---------------------------------------------------------------------------------------------+
+  | Addr[63:28]    | Addr[27:24]           | Addr[23:16]     | Addr[15:2]           | Addr[1:0] |
+  +----------------+-----------------------+-----------------+----------------------------------+
+  | REG_BAR[63:28] | TargetRegister[19:16] | TargetPort[7:0] | TargetRegister[15:2]             |
+  +---------------------------------------------------------------------------------------------+
+
+  SBREG_BAR_20BITADDRESS=0
+  +---------------------------------------------------------------------------------------------+
+  | Addr[63:24]    | Addr[27:24]           | Addr[23:16]     | Addr[15:2]           | Addr[1:0] |
+  +----------------+-----------------------+-----------------+----------------------------------+
+  | REG_BAR[63:24] | REG_BAR[27:24]        | TargetPort[7:0] | TargetRegister[15:2]             |
+  +---------------------------------------------------------------------------------------------+
+**/
+#define PCH_PCR_ADDRESS(Pid, Offset)    (PCH_PCR_BASE_ADDRESS | (UINT32) (((Offset) & 0x0F0000) << 8) | ((UINT8)(Pid) << 16) | (UINT16) ((Offset) & 0xFFFF))
+
+/**
+  PCH PCR boot script accessing macro
+  Those macros are only available for DXE phase.
+**/
+#define PCH_PCR_BOOT_SCRIPT_WRITE(Width, Pid, Offset, Count, Buffer) \
+          S3BootScriptSaveMemWrite (Width, PCH_PCR_ADDRESS (Pid, Offset), Count, Buffer); \
+
+#define PCH_PCR_BOOT_SCRIPT_READ_WRITE(Width, Pid, Offset, DataOr, DataAnd) \
+          S3BootScriptSaveMemReadWrite (Width, PCH_PCR_ADDRESS (Pid, Offset), DataOr, DataAnd); \
+
+#define PCH_PCR_BOOT_SCRIPT_READ(Width, Pid, Offset, BitMask, BitValue) \
+          S3BootScriptSaveMemPoll (Width, PCH_PCR_ADDRESS (Pid, Offset), BitMask, BitValue, 1, 1);
+
+typedef UINT8          PCH_SBI_PID;
+
+/**
+  Read PCR register.
+  It returns PCR register and size in 4bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  Pid      Port ID
+  @param[in]  Offset   Register offset of this Port ID
+
+  @retval UINT32       PCR register value.
+**/
+UINT32
+PchPcrRead32 (
+  IN  PCH_SBI_PID                       Pid,
+  IN  UINT32                            Offset
+  );
+
+/**
+  Read PCR register.
+  It returns PCR register and size in 2bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  Pid      Port ID
+  @param[in]  Offset   Register offset of this Port ID
+
+  @retval UINT16       PCR register value.
+**/
+UINT16
+PchPcrRead16 (
+  IN  PCH_SBI_PID                       Pid,
+  IN  UINT32                            Offset
+  );
+
+/**
+  Read PCR register.
+  It returns PCR register and size in 1bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  Pid      Port ID
+  @param[in]  Offset   Register offset of this Port ID
+
+  @retval UINT8        PCR register value
+**/
+UINT8
+PchPcrRead8 (
+  IN  PCH_SBI_PID                       Pid,
+  IN  UINT32                            Offset
+  );
+
+/**
+  Write PCR register.
+  It programs PCR register and size in 4bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  Pid      Port ID
+  @param[in]  Offset   Register offset of Port ID.
+  @param[in]  Data     Input Data. Must be the same size as Size parameter.
+
+  @retval UINT32       Value written to register
+**/
+UINT32
+PchPcrWrite32 (
+  IN  PCH_SBI_PID                       Pid,
+  IN  UINT32                            Offset,
+  IN  UINT32                            InData
+  );
+
+/**
+  Write PCR register.
+  It programs PCR register and size in 2bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  Pid      Port ID
+  @param[in]  Offset   Register offset of Port ID.
+  @param[in]  Data     Input Data. Must be the same size as Size parameter.
+
+  @retval  UINT16      Value written to register
+**/
+UINT16
+PchPcrWrite16 (
+  IN  PCH_SBI_PID                       Pid,
+  IN  UINT32                            Offset,
+  IN  UINT16                            InData
+  );
+
+/**
+  Write PCR register.
+  It programs PCR register and size in 1bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  Pid      Port ID
+  @param[in]  Offset   Register offset of Port ID.
+  @param[in]  Data     Input Data. Must be the same size as Size parameter.
+
+  @retval  UINT8       Value written to register
+**/
+UINT8
+PchPcrWrite8 (
+  IN  PCH_SBI_PID                       Pid,
+  IN  UINT32                            Offset,
+  IN  UINT8                             InData
+  );
+
+/**
+  Write PCR register.
+  It programs PCR register and size in 4bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  Pid      Port ID
+  @param[in]  Offset   Register offset of Port ID.
+  @param[in]  AndData  AND Data. Must be the same size as Size parameter.
+  @param[in]  OrData   OR Data. Must be the same size as Size parameter.
+
+  @retval  UINT32      Value written to register
+
+**/
+UINT32
+PchPcrAndThenOr32 (
+  IN  PCH_SBI_PID                       Pid,
+  IN  UINT32                            Offset,
+  IN  UINT32                            AndData,
+  IN  UINT32                            OrData
+  );
+
+/**
+  Write PCR register and read back.
+  The read back ensures the PCR cycle is completed before next operation.
+  It programs PCR register and size in 4bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  Pid      Port ID
+  @param[in]  Offset   Register offset of Port ID.
+  @param[in]  AndData  AND Data. Must be the same size as Size parameter.
+  @param[in]  OrData   OR Data. Must be the same size as Size parameter.
+
+  @retval  UINT32      Value read back from the register
+**/
+UINT32
+PchPcrAndThenOr32WithReadback (
+  IN  PCH_SBI_PID                       Pid,
+  IN  UINT32                            Offset,
+  IN  UINT32                            AndData,
+  IN  UINT32                            OrData
+  );
+
+/**
+  Write PCR register.
+  It programs PCR register and size in 2bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  Pid      Port ID
+  @param[in]  Offset   Register offset of Port ID.
+  @param[in]  AndData  AND Data. Must be the same size as Size parameter.
+  @param[in]  OrData   OR Data. Must be the same size as Size parameter.
+
+  @retval UINT16       Value written to register
+
+**/
+UINT16
+PchPcrAndThenOr16 (
+  IN  PCH_SBI_PID                       Pid,
+  IN  UINT32                            Offset,
+  IN  UINT16                            AndData,
+  IN  UINT16                            OrData
+  );
+
+/**
+  Write PCR register.
+  It programs PCR register and size in 1bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  Pid      Port ID
+  @param[in]  Offset   Register offset of Port ID.
+  @param[in]  AndData  AND Data. Must be the same size as Size parameter.
+  @param[in]  OrData   OR Data. Must be the same size as Size parameter.
+
+  @retval  UINT8       Value written to register
+
+**/
+UINT8
+PchPcrAndThenOr8 (
+  IN  PCH_SBI_PID                       Pid,
+  IN  UINT32                            Offset,
+  IN  UINT8                             AndData,
+  IN  UINT8                             OrData
+  );
+
+
+typedef enum {
+  PchIpDmi = 1,
+  PchIpIclk,
+} PCH_IP_PID_ENUM;
+
+#define PCH_INVALID_PID 0
+
+/**
+  Get PCH IP PID number
+
+  @param[in]  IpEnum   PCH IP in PCH_IP_PID_ENUM
+
+  @retval     0        PID of this IP is not supported
+              !0       PID of the IP.
+**/
+PCH_SBI_PID
+PchPcrGetPid (
+  PCH_IP_PID_ENUM  IpEnum
+  );
+
+#endif // _PCH_PCR_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/PcieHelperLib.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/PcieHelperLib.h
new file mode 100644
index 0000000000..8ab20f0db7
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/PcieHelperLib.h
@@ -0,0 +1,173 @@
+/** @file
+  Header file for PCI Express helpers base library
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCIE_HELPER_LIB_H_
+#define _PCIE_HELPER_LIB_H_
+
+#include <PcieRegs.h>
+#include <Library/PciSegmentLib.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <IndustryStandard/Pci.h>
+
+/**
+  Find the Offset to a given Capabilities ID
+  CAPID list:
+    0x01 = PCI Power Management Interface
+    0x04 = Slot Identification
+    0x05 = MSI Capability
+    0x10 = PCI Express Capability
+
+  @param[in] DeviceBase           device's base address
+  @param[in] CapId                CAPID to search for
+
+  @retval 0                       CAPID not found
+  @retval Other                   CAPID found, Offset of desired CAPID
+**/
+UINT8
+PcieBaseFindCapId (
+  IN UINT64  DeviceBase,
+  IN UINT8   CapId
+  );
+
+/**
+  Find the Offset to a given Capabilities ID
+  CAPID list:
+    0x01 = PCI Power Management Interface
+    0x04 = Slot Identification
+    0x05 = MSI Capability
+    0x10 = PCI Express Capability
+
+  @param[in] Segment              Pci Segment Number
+  @param[in] Bus                  Pci Bus Number
+  @param[in] Device               Pci Device Number
+  @param[in] Function             Pci Function Number
+  @param[in] CapId                CAPID to search for
+
+  @retval 0                       CAPID not found
+  @retval Other                   CAPID found, Offset of desired CAPID
+**/
+UINT8
+PcieFindCapId (
+  IN UINT8   Segment,
+  IN UINT8   Bus,
+  IN UINT8   Device,
+  IN UINT8   Function,
+  IN UINT8   CapId
+  );
+
+/**
+  Search and return the offset of desired Pci Express Capability ID
+  CAPID list:
+    0x0001 = Advanced Error Reporting Capability
+    0x0002 = Virtual Channel Capability
+    0x0003 = Device Serial Number Capability
+    0x0004 = Power Budgeting Capability
+
+  @param[in] DeviceBase           device base address
+  @param[in] CapId                Extended CAPID to search for
+
+  @retval 0                       CAPID not found, this includes situation where device doesn't exist
+  @retval Other                   CAPID found, Offset of desired CAPID
+**/
+UINT16
+PcieBaseFindExtendedCapId (
+  IN UINT64  DeviceBase,
+  IN UINT16  CapId
+  );
+
+/**
+  Search and return the offset of desired Pci Express Capability ID
+  CAPID list:
+    0x0001 = Advanced Error Rreporting Capability
+    0x0002 = Virtual Channel Capability
+    0x0003 = Device Serial Number Capability
+    0x0004 = Power Budgeting Capability
+
+  @param[in] Segment              Pci Segment Number
+  @param[in] Bus                  Pci Bus Number
+  @param[in] Device               Pci Device Number
+  @param[in] Function             Pci Function Number
+  @param[in] CapId                Extended CAPID to search for
+
+  @retval 0                       CAPID not found
+  @retval Other                   CAPID found, Offset of desired CAPID
+**/
+UINT16
+PcieFindExtendedCapId (
+  IN UINT8   Segment,
+  IN UINT8   Bus,
+  IN UINT8   Device,
+  IN UINT8   Function,
+  IN UINT16  CapId
+  );
+
+/*
+  Checks device's Slot Clock Configuration
+
+  @param[in] Base            device's base address
+  @param[in] PcieCapOffset   devices Pci express capability list register offset
+
+  @retval TRUE when device device uses slot clock, FALSE otherwise
+*/
+BOOLEAN
+GetScc (
+  UINT64    Base,
+  UINT8     PcieCapOffset
+  );
+
+/*
+  Sets Common Clock Configuration bit for given device.
+  @param[in] PcieCapOffset   devices Pci express capability list register offset
+  @param[in] Base            device's base address
+*/
+VOID
+EnableCcc (
+  UINT64    Base,
+  UINT8     PcieCapOffset
+  );
+
+/*
+  Retrains link behind given device.
+  It only makes sense to call it for downstream ports.
+  If called for upstream port nothing will happen, it won't enter infinite loop.
+
+  @param[in] Base                 device's base address
+  @param[in] PcieCapOffset        devices Pci express capability list register offset
+  @param[boolean] WaitUnitlDone   when TRUE, function waits until link has retrained
+*/
+VOID
+RetrainLink (
+  UINT64  Base,
+  UINT8   PcieCapOffset,
+  BOOLEAN WaitUntilDone
+  );
+
+/*
+  Checks if device at given address exists
+
+  @param[in] Base            device's base address
+
+  @retval TRUE when device exists; FALSE otherwise
+*/
+BOOLEAN
+IsDevicePresent (
+  UINT64 Base
+  );
+
+/*
+  Checks if device is a multifunction device
+
+  @param[in] Base            device's base address
+
+  @retval TRUE if multifunction; FALSE otherwise
+*/
+BOOLEAN
+IsMultifunctionDevice (
+  UINT64 Base
+  );
+#endif // _PCIE_HELPER_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/PmcLib.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/PmcLib.h
new file mode 100644
index 0000000000..0b8ad7a182
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/PmcLib.h
@@ -0,0 +1,355 @@
+/** @file
+  Header file for PmcLib.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PMC_LIB_H_
+#define _PMC_LIB_H_
+
+#pragma pack(1)
+
+typedef enum {
+  PmcTPch25_10us = 0,
+  PmcTPch25_100us,
+  PmcTPch25_1ms,
+  PmcTPch25_10ms,
+} PMC_TPCH25_TIMING;
+
+typedef enum {
+  PmcNotASleepState,
+  PmcInS0State,
+  PmcS1SleepState,
+  PmcS2SleepState,
+  PmcS3SleepState,
+  PmcS4SleepState,
+  PmcS5SleepState,
+  PmcUndefinedState,
+} PMC_SLEEP_STATE;
+
+typedef struct {
+  UINT32    Buf0;
+  UINT32    Buf1;
+  UINT32    Buf2;
+  UINT32    Buf3;
+} PMC_IPC_COMMAND_BUFFER;
+
+//
+// Structure to Check different attributes for CrashLog supported by PMC.
+//
+typedef union {
+  struct {
+    UINT32  Avail      : 1;        ///< CrashLog feature availability bit
+    UINT32  Dis        : 1;        ///< CrasLog Disable bit
+    UINT32  Rsvd       : 2;        ///< Reserved
+    UINT32  Size       : 12;       ///< CrasLog data size. (If it is zero, use default size 0xC00)
+    UINT32  BaseOffset : 16;       ///< Start offset of CrashLog in PMC SSRAM
+  } Bits;
+  struct {
+    UINT32  Avail      : 1;        ///< CrashLog feature availability bit
+    UINT32  Dis        : 1;        ///< CrasLog Disable bit
+    UINT32  Mech       : 2;        ///< CrashLog mechanism
+    UINT32  ManuTri    : 1;        ///< Manul trigger command.
+    UINT32  Clr        : 1;        ///< Clear Command
+    UINT32  AllReset   : 1;        ///< Trigger on all reset command
+    UINT32  ReArm      : 1;        ///< Re-arm command
+    UINT32  Rsvd       : 20;       ///< Pch Specific reserved
+    UINT32  CrashLogReq: 1;        ///< Crash log requestor flow
+    UINT32  TriArmedSts: 1;        ///< Trigger armed status, re-arm indication bit.
+    UINT32  TriAllReset: 1;        ///< Trigger on all resets status
+    UINT32  CrashDisSts: 1;        ///< Crash log disabled status
+    UINT32  PchRsvd    : 16;       ///< Pch Specific reserved
+    UINT32  DesTableOffset: 16;    ///< Descriptor Table offset
+  } Bits64;
+  UINT32  Uint32;
+  UINT64  Uint64;
+} PMC_IPC_DISCOVERY_BUF;
+
+typedef union {
+  struct {
+    UINT32 Offset   : 16;
+    UINT32 Size     : 16;
+  } Info;
+  UINT32 Uint32;
+} PMC_CRASHLOG_RECORDS;
+
+typedef struct PmcCrashLogLink {
+  PMC_CRASHLOG_RECORDS      Record;
+  UINT64                    AllocateAddress;
+  struct PmcCrashLogLink    *Next;
+} PMC_CRASHLOG_LINK;
+
+#pragma pack()
+
+/**
+  Get PCH ACPI base address.
+
+  @retval Address                   Address of PWRM base address.
+**/
+UINT16
+PmcGetAcpiBase (
+  VOID
+  );
+
+/**
+  Get PCH PWRM base address.
+
+  @retval Address                   Address of PWRM base address.
+**/
+UINT32
+PmcGetPwrmBase (
+  VOID
+  );
+
+/**
+  This function sets tPCH25 timing
+
+  @param[in] TimingValue       tPCH25 timing value (10us, 100us, 1ms, 10ms)
+**/
+VOID
+PmcSetTPch25Timing (
+  IN PMC_TPCH25_TIMING    TimingValue
+  );
+
+/**
+  This function checks if RTC Power Failure occurred by
+  reading RTC_PWR_FLR bit
+
+  @retval RTC Power Failure state: TRUE  - Battery is always present.
+                                   FALSE - CMOS is cleared.
+**/
+BOOLEAN
+PmcIsRtcBatteryGood (
+  VOID
+  );
+
+/**
+  This function checks if Power Failure occurred by
+  reading PWR_FLR bit
+
+  @retval Power Failure state
+**/
+BOOLEAN
+PmcIsPowerFailureDetected (
+  VOID
+  );
+
+/**
+  This function checks if Power Failure occurred by
+  reading SUS_PWR_FLR bit
+
+  @retval SUS Power Failure state
+**/
+BOOLEAN
+PmcIsSusPowerFailureDetected (
+  VOID
+  );
+
+/**
+  This function clears Power Failure status (PWR_FLR)
+**/
+VOID
+PmcClearPowerFailureStatus (
+  VOID
+  );
+
+/**
+  This function clears Global Reset status (GBL_RST_STS)
+**/
+VOID
+PmcClearGlobalResetStatus (
+  VOID
+  );
+
+/**
+  This function clears Host Reset status (HOST_RST_STS)
+**/
+VOID
+PmcClearHostResetStatus (
+  VOID
+  );
+
+/**
+  This function clears SUS Power Failure status (SUS_PWR_FLR)
+**/
+VOID
+PmcClearSusPowerFailureStatus (
+  VOID
+  );
+
+/**
+  This function sets state to which platform will get after power is reapplied
+
+  @param[in] PowerStateAfterG3          0: S0 state (boot)
+                                        1: S5/S4 State
+**/
+VOID
+PmcSetPlatformStateAfterPowerFailure (
+  IN UINT8 PowerStateAfterG3
+  );
+
+/**
+  This function enables Power Button SMI
+**/
+VOID
+PmcEnablePowerButtonSmi (
+  VOID
+  );
+
+/**
+  This function disables Power Button SMI
+**/
+VOID
+PmcDisablePowerButtonSmi (
+  VOID
+  );
+
+/**
+  This function reads PM Timer Count driven by 3.579545 MHz clock
+
+  @retval PM Timer Count
+**/
+UINT32
+PmcGetTimerCount (
+  VOID
+  );
+
+/**
+  Get Sleep Type that platform has waken from
+
+  @retval SleepType                Sleep Type
+**/
+PMC_SLEEP_STATE
+PmcGetSleepTypeAfterWake (
+  VOID
+  );
+
+/**
+  Clear PMC Wake Status
+**/
+VOID
+PmcClearWakeStatus (
+  VOID
+  );
+
+/**
+  Configure sleep state
+
+  @param[in] SleepState         S0/S1/S3/S4/S5, refer to PMC_SLEEP_STATE
+**/
+VOID
+PmcSetSleepState (
+  PMC_SLEEP_STATE  SleepState
+  );
+
+/**
+  Check if platform boots after shutdown caused by power button override event
+
+  @retval  TRUE   Power Button Override occurred in last system boot
+  @retval  FALSE  Power Button Override didn't occur
+**/
+BOOLEAN
+PmcIsPowerButtonOverrideDetected (
+  VOID
+  );
+
+/**
+  This function will set the DISB - DRAM Initialization Scratchpad Bit.
+**/
+VOID
+PmcSetDramInitScratchpad (
+  VOID
+  );
+
+/**
+  Check global SMI enable is set
+
+  @retval TRUE  Global SMI enable is set
+          FALSE Global SMI enable is not set
+**/
+BOOLEAN
+PmcIsGblSmiEn (
+  VOID
+  );
+
+/**
+  This function checks if SMI Lock is set
+
+  @retval SMI Lock state
+**/
+BOOLEAN
+PmcIsSmiLockSet (
+  VOID
+  );
+
+/**
+  This function checks if Debug Mode is locked
+
+  @retval Debug Mode Lock state
+**/
+BOOLEAN
+PmcIsDebugModeLocked (
+  VOID
+  );
+
+/**
+  Check TCO second timeout status.
+
+  @retval  TRUE   TCO reboot happened.
+  @retval  FALSE  TCO reboot didn't happen.
+**/
+BOOLEAN
+TcoSecondToHappened (
+  VOID
+  );
+
+/**
+  This function clears the Second TO status bit
+**/
+VOID
+TcoClearSecondToStatus (
+  VOID
+  );
+
+/**
+  Check TCO SMI ENABLE is locked
+
+  @retval TRUE  TCO SMI ENABLE is locked
+          FALSE TCO SMI ENABLE is not locked
+**/
+BOOLEAN
+TcoIsSmiLock (
+  VOID
+  );
+
+/**
+  Check if user wants to turn off in PEI phase
+
+**/
+VOID
+CheckPowerOffNow(
+  VOID
+  );
+
+
+/**
+  Clear any SMI status or wake status left from boot.
+**/
+VOID
+ClearSmiAndWake (
+  VOID
+  );
+
+/**
+  Function to check if Dirty Warm Reset occurs
+  (Global Reset has been converted to Host Reset)
+
+  @reval TRUE DWR occurs
+  @reval FALSE Normal boot flow
+**/
+BOOLEAN
+PmcIsDwrBootMode (
+  VOID
+  );
+
+#endif // _PMC_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/ResetSystemLib.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/ResetSystemLib.h
new file mode 100644
index 0000000000..9ab55ad9d0
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/ResetSystemLib.h
@@ -0,0 +1,79 @@
+/** @file
+  System reset Library Services.  This library class defines a set of
+  methods that reset the whole system.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __RESET_SYSTEM_LIB_H__
+#define __RESET_SYSTEM_LIB_H__
+
+/**
+  This function causes a system-wide reset (cold reset), in which
+  all circuitry within the system returns to its initial state. This type of reset
+  is asynchronous to system operation and operates without regard to
+  cycle boundaries.
+
+  If this function returns, it means that the system does not support cold reset.
+**/
+VOID
+EFIAPI
+ResetCold (
+  VOID
+  );
+
+/**
+  This function causes a system-wide initialization (warm reset), in which all processors
+  are set to their initial state. Pending cycles are not corrupted.
+
+  If this function returns, it means that the system does not support warm reset.
+**/
+VOID
+EFIAPI
+ResetWarm (
+  VOID
+  );
+
+/**
+  This function causes the system to enter a power state equivalent
+  to the ACPI G2/S5 or G3 states.
+
+  If this function returns, it means that the system does not support shutdown reset.
+**/
+VOID
+EFIAPI
+ResetShutdown (
+  VOID
+  );
+
+/**
+  This function causes the system to enter S3 and then wake up immediately.
+
+  If this function returns, it means that the system does not support S3 feature.
+**/
+VOID
+EFIAPI
+EnterS3WithImmediateWake (
+  VOID
+  );
+
+/**
+  This function causes a systemwide reset. The exact type of the reset is
+  defined by the EFI_GUID that follows the Null-terminated Unicode string passed
+  into ResetData. If the platform does not recognize the EFI_GUID in ResetData
+  the platform must pick a supported reset type to perform.The platform may
+  optionally log the parameters from any non-normal reset that occurs.
+
+  @param[in]  DataSize   The size, in bytes, of ResetData.
+  @param[in]  ResetData  The data buffer starts with a Null-terminated string,
+                         followed by the EFI_GUID.
+**/
+VOID
+EFIAPI
+ResetPlatformSpecific (
+  IN UINTN   DataSize,
+  IN VOID    *ResetData
+  );
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/SataLib.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/SataLib.h
new file mode 100644
index 0000000000..bc1555ed19
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/SataLib.h
@@ -0,0 +1,112 @@
+/** @file
+  Header file for SataLib.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SATA_LIB_H_
+#define _SATA_LIB_H_
+
+#define SATA_1_CONTROLLER_INDEX             0
+#define SATA_2_CONTROLLER_INDEX             1
+#define SATA_3_CONTROLLER_INDEX             2
+
+/**
+  Get Maximum Sata Port Number
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval     Maximum Sata Port Number
+**/
+UINT8
+MaxSataPortNum (
+  IN UINT32     SataCtrlIndex
+  );
+
+/**
+  Gets Maximum Sata Controller Number
+
+  @retval Maximum Sata Controller Number
+**/
+UINT8
+MaxSataControllerNum (
+  VOID
+  );
+
+/**
+  Get SATA controller's Port Present Status
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval     Port Present Status
+**/
+UINT8
+GetSataPortPresentStatus (
+  IN UINT32  SataCtrlIndex
+  );
+
+/**
+  Get SATA controller Function Disable Status
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval 0 SATA Controller is not Function Disabled
+  @retval 1 SATA Controller is Function Disabled
+**/
+BOOLEAN
+SataControllerFunctionDisableStatus (
+  IN UINT32  SataCtrlIndex
+  );
+
+/**
+  Get SATA controller ABAR size
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval SATA controller ABAR size
+**/
+UINT32
+GetSataAbarSize (
+  IN UINT32  SataCtrlIndex
+  );
+
+/**
+  Get SATA controller AHCI base address
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval SATA controller AHCI base address
+**/
+UINT32
+GetSataAhciBase (
+  IN UINT32  SataCtrlIndex
+  );
+
+/**
+  Check if SATA controller supports RST remapping
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval     TRUE                Controller supports remapping
+  @retval     FALSE               Controller does not support remapping
+**/
+BOOLEAN
+IsRemappingSupportedOnSata (
+  IN UINT32  SataCtrlIndex
+  );
+
+/**
+  Checks if SoC supports the SATA PGD power down on given
+  SATA controller.
+
+  @param[in] SataCtrlIndex  SATA controller index
+
+  @retval TRUE   SATA PGD power down supported
+  @retval FALSE  SATA PGD power down not supported
+**/
+BOOLEAN
+IsSataPowerGatingSupported (
+  IN UINT32 SataCtrlIndex
+  );
+
+#endif // _SATA_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/SerialIoAccessLib.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/SerialIoAccessLib.h
new file mode 100644
index 0000000000..3c8aae6ac2
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/SerialIoAccessLib.h
@@ -0,0 +1,113 @@
+/** @file
+  Header file for Serial Io Common Lib
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SERIAL_IO_ACCESS_LIB_H_
+#define _SERIAL_IO_ACCESS_LIB_H_
+
+/**
+  Returns BAR0
+
+  @param[in] PciCfgBase         Pci Config Base
+
+  @retval    64bit MMIO BAR Address
+**/
+UINT64
+GetSerialIoBar (
+  IN UINT64        PciCfgBase
+  );
+
+/**
+  Returns I2C Pci Config Space
+
+  @param[in] I2cNumber         I2C Number
+
+  @retval    I2C Pci Config Space Address
+**/
+UINT64
+GetSerialIoI2cPciCfg (
+  IN UINT8        I2cNumber
+  );
+
+/**
+  Returns SPI Pci Config Space
+
+  @param[in] SpiNumber         SPI Number
+
+  @retval    SPI Pci Config Space Address
+**/
+UINT64
+GetSerialIoSpiPciCfg (
+  IN UINT8        SpiNumber
+  );
+
+/**
+  Returns UART Pci Config Space
+
+  @param[in] UartNumber         UART Number
+
+  @retval    UART Pci Config Space Address
+**/
+UINT64
+GetSerialIoUartPciCfg (
+  IN UINT8        UartNumber
+  );
+
+/**
+  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
+  );
+
+/**
+  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
+  );
+
+/**
+  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
+  );
+
+/**
+  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
+  );
+
+#endif // _SERIAL_IO_ACCESS_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/SiConfigBlockLib.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/SiConfigBlockLib.h
new file mode 100644
index 0000000000..7732ccf59e
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/SiConfigBlockLib.h
@@ -0,0 +1,56 @@
+/** @file
+  Prototype of the SiConfigBlockLib library.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SI_CONFIG_BLOCK_LIB_H_
+#define _SI_CONFIG_BLOCK_LIB_H_
+
+
+typedef
+VOID
+(*LOAD_DEFAULT_FUNCTION) (
+  IN VOID   *ConfigBlockPointer
+  );
+
+typedef struct {
+  EFI_GUID               *Guid;
+  UINT16                 Size;
+  UINT8                  Revision;
+  LOAD_DEFAULT_FUNCTION  LoadDefault;
+} COMPONENT_BLOCK_ENTRY;
+
+/**
+  GetComponentConfigBlockTotalSize get config block table total size.
+
+  @param[in] ComponentBlocks    Component blocks array
+  @param[in] TotalBlockCount    Number of blocks
+
+  @retval                       Size of config block table
+**/
+UINT16
+EFIAPI
+GetComponentConfigBlockTotalSize (
+  IN COMPONENT_BLOCK_ENTRY *ComponentBlocks,
+  IN UINT16                TotalBlockCount
+  );
+
+/**
+  AddComponentConfigBlocks add all config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add config blocks
+  @param[in] ComponentBlocks            Config blocks array
+  @param[in] TotalBlockCount            Number of blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+AddComponentConfigBlocks (
+  IN VOID                  *ConfigBlockTableAddress,
+  IN COMPONENT_BLOCK_ENTRY *ComponentBlocks,
+  IN UINT16                TotalBlockCount
+  );
+#endif // _SI_CONFIG_BLOCK_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/SpiAccessLib.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/SpiAccessLib.h
new file mode 100644
index 0000000000..50f9e048b3
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/SpiAccessLib.h
@@ -0,0 +1,290 @@
+/** @file
+  SPI library header for abstraction of SPI HW registers accesses
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SPI_ACCESS_LIB_H_
+#define _SPI_ACCESS_LIB_H_
+
+/**
+  Returns SPI PCI Config Space base address
+
+  @retval  UINT64  SPI Config Space base address
+**/
+UINT64
+SpiGetPciCfgAddress (
+  VOID
+  );
+
+/**
+  Returns SPI BAR0 value
+
+  @retval  UINT32  PCH SPI BAR0 value
+**/
+UINT32
+SpiGetBar0 (
+  VOID
+  );
+
+/**
+  Returns SPI Device number
+
+  @retval UINT8   PCH SPI Device number
+**/
+UINT8
+SpiDeviceNumber (
+  VOID
+  );
+
+/**
+  Returns SPI Function number
+
+  @retval UINT8   PCH SPI Function number
+**/
+UINT8
+SpiFunctionNumber (
+  VOID
+  );
+
+/**
+  Returns descriptor signature
+
+  @retval UINT32    Descriptor signature
+**/
+UINT32
+SpiGetDescriptorSignature (
+  VOID
+  );
+
+/**
+  Returns supported features and R/W frequencies of Flash Component
+
+  @retval UINT32    Flash Component features descriptor
+**/
+UINT32
+SpiGetFlashComponentDescription (
+  VOID
+  );
+
+/**
+  Returns number of Flash Components
+
+  @retval UINT32    Flash components number
+**/
+UINT32
+SpiGetFlashComponentsNumber (
+  VOID
+  );
+
+/**
+  Returns total Flash size with regards to number of flash components
+
+  @retval UINT32    Total Flash Memory size
+**/
+UINT32
+SpiGetTotalFlashSize (
+  VOID
+  );
+
+/**
+  Checks if PCH SPI Controler is present and available
+
+  @retval TRUE    PCH SPI controller is avaialable
+  @retval FALSE   PCH SPI controller is not available
+**/
+BOOLEAN
+SpiIsControllerAvailable (
+  VOID
+  );
+
+/**
+  Checks BIOS lock bits for proper value and checks if write protection is enabled
+  Expected vales are: LE bit set, EISS bit set and WPD bit cleared
+
+  @retval  TRUE    All protection bits are set correctly
+  @retval  FALSE   Not all protection bits had exepcted values
+**/
+BOOLEAN
+SpiIsWriteProtectionEnabled (
+  VOID
+  );
+
+/**
+  Returns Flash Descriptor Override Pin Strap status
+
+  @retval TRUE     Flash Descriptor override is enabled
+  @retval FALSE    Flash Descriptor override is disabled
+**/
+BOOLEAN
+SpiIsFlashDescriptorOverrideEnabled (
+  VOID
+  );
+
+/**
+  Returns Flash Configuration Lock Down bit status
+
+  @retval TRUE    Flash Configuration Lock Down bit is set
+  @retval FALSE   Flash Configuration Lock Down bit is not set
+**/
+BOOLEAN
+SpiIsFlashConfigurationLockDownEnabled (
+  VOID
+  );
+
+/**
+  Returns Top Swap functionality enable state
+
+  @retval TRUE    Top Swap is enabled
+  @retval FALSE   Top Swap is disabled
+**/
+BOOLEAN
+SpiIsTopSwapEnabled (
+  VOID
+  );
+
+/**
+  Return Component Property Parameter Table for a given component number
+
+  @param[in]  ComponentNumber   SPI Component number
+  @param[out] CppTable          Component Poperty Parameter Table value
+
+  @retval TRUE  Vendor Specific Component Capabilities Register value was read
+  @reval  FALSE Vendor Specific Component Capabilities Register value was not present
+**/
+BOOLEAN
+SpiGetComponentPropertyParameterTable (
+  IN  UINT8  ComponentNumber,
+  OUT UINT32 *CppTable
+  );
+
+/**
+  Returns valid bit status in given Component Property Parameter Table
+
+  @param[in] CppTable          Component Poperty Parameter Table value
+
+  @retval TRUE    Valid bit is set
+  @reval  FALSE   Valid bit is not set
+**/
+BOOLEAN
+SpiIsCppValidBitSet (
+  IN UINT32  CppTable
+  );
+
+/**
+  Checks if Flash Descriptor is valid
+
+  @retval TRUE  Flash Descriptor is valid
+  @retval FALSE Flash Descriptor is invalid
+**/
+BOOLEAN
+SpiIsFlashDescriptorValid (
+  VOID
+  );
+
+/**
+  Returns masked BIOS Master Read Access
+
+  @retval UINT32    Already masked BIOS Master Read Access
+**/
+UINT32
+SpiGetMasterReadAccess (
+  VOID
+  );
+
+/**
+  Returns masked BIOS Master Write Access
+
+  @retval UINT32    Already masked BIOS Master Write Access
+**/
+UINT32
+SpiGetMasterWriteAccess (
+  VOID
+  );
+
+/**
+  Returns GbE Region Access rights
+
+  @retval UINT32    GbE Region access rights
+**/
+UINT32
+SpiGetGbeRegionAccess (
+  VOID
+  );
+
+/**
+  Returns CSME region access rights
+
+  @retval UINT32    CSME Region Access rights
+**/
+UINT32
+SpiGetCsmeRegionAccess (
+  VOID
+  );
+
+/**
+  Returns EC region access right
+
+  @retval UINT32     EC Region access rights
+**/
+UINT32
+SpiGetEcRegionAccess (
+  VOID
+  );
+
+/**
+  Checks if Slave Attached Flash (SAF) mode is active
+
+  @retval TRUE    SAF mode is active
+  @retval FALSE   SAF mode is not active
+**/
+BOOLEAN
+SpiIsSafModeActive (
+  VOID
+  );
+
+/**
+  Checks validity of GbE region
+
+  @retval TRUE    GbE region is valid
+  @retval FALSE   GbE regios in invalid
+**/
+BOOLEAN
+SpiIsGbeRegionValid (
+  VOID
+  );
+
+/**
+  Returns status of BIOS Interface Lockdown
+
+  @retval TRUE  BIOS Interface Lockdown is enabled
+  @retval FALSE BIOS Interface Lockdown is disabled
+**/
+BOOLEAN
+SpiIsBiosInterfaceLockdownEnabled (
+  VOID
+  );
+
+/**
+  Returns TRUE if BIOS Boot Strap is set to SPI
+
+  @retval TRUE    BIOS Boot strap is set to SPI
+  @retval FALSE   BIOS Boot strap is set to LPC/eSPI
+**/
+BOOLEAN
+SpiIsBiosBootFromSpi (
+  VOID
+  );
+
+/**
+  Check SPI write status disable is set
+
+  @retval TRUE    Write status disable is set
+  @retval FALSE   Write status disable is not set
+**/
+BOOLEAN
+SpiIsWriteStatusDisable (
+  VOID
+  );
+
+#endif // _SPI_ACCESS_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/VtdInfoLib.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/VtdInfoLib.h
new file mode 100644
index 0000000000..69eed8d32d
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Library/VtdInfoLib.h
@@ -0,0 +1,53 @@
+/** @file
+  Header file for VtdInfoLib.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _VTD_INFO_LIB_H_
+#define _VTD_INFO_LIB_H_
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/HobLib.h>
+
+#define VTD_ENGINE_NUMBER             7
+
+#pragma pack(1)
+
+/**
+  Get VTD Engine Base Address from PCD values.
+
+  @param[in]  VtdEngineNumber        - Engine number for which VTD Base Adderess is required.
+
+  @retval   VTD Engine Base Address
+**/
+UINT32
+GetVtdBaseAddress (
+  IN UINT8        VtdEngineNumber
+  );
+
+/**
+  Read VTD Engine Base Address from VTD BAR Offsets.
+
+  @param[in]  VtdEngineNumber        - Engine number for which VTD Base Adderess is required.
+
+  @retval   VTD Engine Base Address
+**/
+UINT32
+ReadVtdBaseAddress (
+  IN UINT8        VtdEngineNumber
+  );
+
+/**
+  GetMaxVtdEngineNumber: Get Maximum Vtd Engine Number
+
+  @retval Vtd Engine Number
+**/
+UINT8
+GetMaxVtdEngineNumber(
+  VOID
+);
+
+#pragma pack()
+#endif // _VTD_INFO_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Ppi/PeiPreMemSiDefaultPolicy.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Ppi/PeiPreMemSiDefaultPolicy.h
new file mode 100644
index 0000000000..3fd917c2b9
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Ppi/PeiPreMemSiDefaultPolicy.h
@@ -0,0 +1,34 @@
+/** @file
+  This file defines the function to initialize default silicon policy PPI.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_PREMEM_SI_DEFAULT_POLICY_INIT_PPI_H_
+#define _PEI_PREMEM_SI_DEFAULT_POLICY_INIT_PPI_H_
+
+//
+// Forward declaration for the PEI_PREMEM_SI_DEFAULT_POLICY_INIT_PPI.
+//
+typedef struct _PEI_PREMEM_SI_DEFAULT_POLICY_INIT_PPI PEI_PREMEM_SI_DEFAULT_POLICY_INIT_PPI;
+
+/**
+  Initialize and install default silicon policy PPI
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PEI_PREMEM_POLICY_INIT) (
+  VOID
+  );
+
+///
+/// This PPI provides function to install default silicon policy
+///
+struct _PEI_PREMEM_SI_DEFAULT_POLICY_INIT_PPI {
+  PEI_PREMEM_POLICY_INIT   PeiPreMemPolicyInit;   ///< PeiPreMemPolicyInit()
+};
+
+extern EFI_GUID gSiPreMemDefaultPolicyInitPpiGuid;
+
+#endif // _PEI_PREMEM_SI_DEFAULT_POLICY_INIT_PPI_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Ppi/PeiSiDefaultPolicy.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Ppi/PeiSiDefaultPolicy.h
new file mode 100644
index 0000000000..9cb34728cc
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Ppi/PeiSiDefaultPolicy.h
@@ -0,0 +1,33 @@
+/** @file
+  This file defines the function to initialize default silicon policy PPI.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PEI_SI_DEFAULT_POLICY_INIT_PPI_H_
+#define _PEI_SI_DEFAULT_POLICY_INIT_PPI_H_
+
+//
+// Forward declaration for the PEI_SI_DEFAULT_POLICY_INIT_PPI.
+//
+typedef struct _PEI_SI_DEFAULT_POLICY_INIT_PPI PEI_SI_DEFAULT_POLICY_INIT_PPI;
+
+/**
+  Initialize and install default silicon policy PPI
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PEI_POLICY_INIT) (
+  VOID
+  );
+
+///
+/// This PPI provides function to install default silicon policy
+///
+struct _PEI_SI_DEFAULT_POLICY_INIT_PPI {
+  PEI_POLICY_INIT   PeiPolicyInit;    ///< PeiPolicyInit()
+};
+
+extern EFI_GUID gSiDefaultPolicyInitPpiGuid;
+
+#endif // _PEI_SI_DEFAULT_POLICY_INIT_PPI_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Ppi/SiPolicy.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Ppi/SiPolicy.h
new file mode 100644
index 0000000000..5f4d467439
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Ppi/SiPolicy.h
@@ -0,0 +1,75 @@
+/** @file
+  Silicon Policy PPI is used for specifying platform
+  related Intel silicon information and policy setting.
+  This PPI is consumed by the silicon PEI modules and carried
+  over to silicon DXE modules.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SI_POLICY_PPI_H_
+#define _SI_POLICY_PPI_H_
+
+#include <SiPolicyStruct.h>
+#include <PchPolicyCommon.h>
+#include <PchPreMemPolicyCommon.h>
+#include <MePolicyCommon.h>
+#include <CpuPolicyCommon.h>
+#include <Uefi.h>
+#include <Library/ConfigBlockLib.h>
+
+#ifndef DISABLED
+#define DISABLED  0
+#endif
+#ifndef ENABLED
+#define ENABLED   1
+#endif
+
+extern EFI_GUID gSiPreMemPolicyPpiGuid;
+extern EFI_GUID gSiPolicyPpiGuid;
+
+
+#include <GraphicsConfig.h>
+extern EFI_GUID gGraphicsPeiPreMemConfigGuid;
+extern EFI_GUID gGraphicsPeiConfigGuid;
+
+#include <VtdConfig.h>
+extern EFI_GUID gVtdConfigGuid;
+
+#include <GnaConfig.h>
+extern EFI_GUID gGnaConfigGuid;
+
+#include <CpuPcieConfig.h>
+extern EFI_GUID gCpuPciePeiPreMemConfigGuid;
+extern EFI_GUID gCpuPcieRpConfigGuid;
+
+#include <HybridGraphicsConfig.h>
+extern EFI_GUID gHybridGraphicsConfigGuid;
+
+#include <ConfigBlock/PramPreMemConfig.h>
+#include <MemoryConfig.h>
+extern EFI_GUID gMemoryConfigGuid;
+extern EFI_GUID gMemoryConfigNoCrcGuid;
+
+#include <ConfigBlock/SaMiscPeiPreMemConfig.h>
+extern EFI_GUID gSaMiscPeiPreMemConfigGuid;
+
+#include <ConfigBlock/SaMiscPeiConfig.h>
+extern EFI_GUID gSaMiscPeiConfigGuid;
+
+
+#include <TraceHubConfig.h>
+extern EFI_GUID gCpuTraceHubConfigGuid;
+
+#include <HostBridgeConfig.h>
+extern EFI_GUID gHostBridgePeiPreMemConfigGuid;
+extern EFI_GUID gHostBridgePeiConfigGuid;
+
+#include <CpuDmiPreMemConfig.h>
+extern EFI_GUID gCpuDmiPreMemConfigGuid;
+
+typedef struct _SI_PREMEM_POLICY_STRUCT SI_PREMEM_POLICY_PPI;
+typedef struct _SI_POLICY_STRUCT SI_POLICY_PPI;
+
+#endif // _SI_POLICY_PPI_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Protocol/GopComponentName2.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Protocol/GopComponentName2.h
new file mode 100644
index 0000000000..1d69ee0e8d
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Protocol/GopComponentName2.h
@@ -0,0 +1,61 @@
+/** @file
+  Protocol to retrieve the GOP driver version
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _GOP_COMPONENT_NAME2_H_
+#define _GOP_COMPONENT_NAME2_H_
+
+
+typedef struct _GOP_COMPONENT_NAME2_PROTOCOL  GOP_COMPONENT_NAME2_PROTOCOL;
+
+///
+/// GOP Component protocol for retrieving driver name
+///
+typedef
+EFI_STATUS
+(EFIAPI *GOP_COMPONENT_NAME2_GET_DRIVER_NAME) (
+  IN  GOP_COMPONENT_NAME2_PROTOCOL * This,
+  IN  CHAR8                           *Language,
+  OUT CHAR16                          **DriverName
+  );
+
+///
+/// GOP Component protocol for retrieving controller name
+///
+typedef
+EFI_STATUS
+(EFIAPI *GOP_COMPONENT_NAME2_GET_CONTROLLER_NAME) (
+  IN  GOP_COMPONENT_NAME2_PROTOCOL          * This,
+  IN  EFI_HANDLE                               ControllerHandle,
+  IN  EFI_HANDLE                               ChildHandle OPTIONAL,
+  IN  CHAR8                                    *Language,
+  OUT CHAR16                                   **ControllerName
+  );
+
+///
+/// GOP Component protocol for retrieving driver version
+///
+typedef
+EFI_STATUS
+(EFIAPI *GOP_COMPONENT_NAME2_GET_DRIVER_VERSION) (
+  IN  GOP_COMPONENT_NAME2_PROTOCOL          * This,
+  IN  CHAR8                                    *Language,
+  OUT CHAR16                                   **DriverVersion
+  );
+
+/**
+  GOP Component protocol\n
+  This protocol will be installed by GOP driver and can be used to retrieve GOP information.
+**/
+struct _GOP_COMPONENT_NAME2_PROTOCOL {
+  GOP_COMPONENT_NAME2_GET_DRIVER_NAME      GetDriverName;          ///< Protocol function to get driver name
+  GOP_COMPONENT_NAME2_GET_DRIVER_VERSION   GetDriverVersion;       ///< Protocol function to get driver version
+  GOP_COMPONENT_NAME2_GET_CONTROLLER_NAME  GetControllerName;      ///< Protocol function to get controller name
+  CHAR8                                    *SupportedLanguages;    ///< Number of Supported languages.
+};
+
+extern EFI_GUID gGopComponentName2ProtocolGuid;
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Protocol/GopPolicy.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Protocol/GopPolicy.h
new file mode 100644
index 0000000000..c8dc17008e
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Protocol/GopPolicy.h
@@ -0,0 +1,73 @@
+/** @file
+  Interface definition for GopPolicy Protocol.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _GOP_POLICY_PROTOCOL_H_
+#define _GOP_POLICY_PROTOCOL_H_
+
+
+#define GOP_POLICY_PROTOCOL_REVISION_01  0x01
+#define GOP_POLICY_PROTOCOL_REVISION_03  0x03
+
+typedef enum {
+  LidClosed,
+  LidOpen,
+  LidStatusMax
+} LID_STATUS;
+
+typedef enum {
+  Docked,
+  UnDocked,
+  DockStatusMax
+} DOCK_STATUS;
+
+///
+/// Function to retrieve LID status
+///
+typedef
+EFI_STATUS
+(EFIAPI *GET_PLATFORM_LID_STATUS) (
+  OUT LID_STATUS * CurrentLidStatus
+  );
+
+///
+/// Function to retrieve Dock status
+///
+typedef
+EFI_STATUS
+(EFIAPI *GET_PLATFORM_DOCK_STATUS) (
+ OUT DOCK_STATUS  CurrentDockStatus
+);
+
+///
+/// Function to retrieve VBT table address and size
+///
+typedef
+EFI_STATUS
+(EFIAPI *GET_VBT_DATA) (
+  OUT EFI_PHYSICAL_ADDRESS * VbtAddress,
+  OUT UINT32               *VbtSize
+  );
+
+/**
+  System Agent Graphics Output Protocol (GOP) - Policy Protocol\n
+  Graphics Output Protocol (GOP) is a UEFI API replacing legacy Video ROMs for EFI boot\n
+  When GOP Driver is used this protocol can be consumed by GOP driver or platform code for GOP relevant initialization\n
+  All functions in this protocol should be initialized by platform code basing on platform implementation\n
+**/
+typedef struct {
+  UINT32                    Revision;              ///< Protocol revision
+  GET_PLATFORM_LID_STATUS   GetPlatformLidStatus;  ///< Protocol function to get Lid Status. Platform code should provide this function basing on design.
+  GET_VBT_DATA              GetVbtData;            ///< Protocol function to get Vbt Data address and size. Platform code should provide this function basing on design.
+  GET_PLATFORM_DOCK_STATUS  GetPlatformDockStatus;  ///< Function pointer for get platform dock status.
+  EFI_GUID                  GopOverrideGuid;        ///< A GUID provided by BIOS in case GOP is to be overridden.
+} GOP_POLICY_PROTOCOL;
+
+extern EFI_GUID gGopPolicyProtocolGuid;
+extern EFI_GUID gGen12PolicyProtocolGuid;
+extern EFI_GUID gGen9PolicyProtocolGuid;
+extern EFI_GUID gIntelGraphicsVbtGuid;
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Protocol/IgdOpRegion.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Protocol/IgdOpRegion.h
new file mode 100644
index 0000000000..c030f771e3
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Protocol/IgdOpRegion.h
@@ -0,0 +1,22 @@
+/** @file
+  This file is part of the IGD OpRegion Implementation.  The IGD OpRegion is
+  an interface between system BIOS, ASL code, and Graphics drivers.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _IGD_OPREGION_PROTOCOL_H_
+#define _IGD_OPREGION_PROTOCOL_H_
+
+#include <IndustryStandard/IgdOpRegion.h>
+
+extern EFI_GUID gIgdOpRegionProtocolGuid;
+
+///
+/// IGD OpRegion Protocol
+///
+typedef struct {
+  IGD_OPREGION_STRUCTURE  *OpRegion; ///< IGD Operation Region Structure
+} IGD_OPREGION_PROTOCOL;
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Protocol/Spi.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Protocol/Spi.h
new file mode 100644
index 0000000000..c13dc5a5f5
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Protocol/Spi.h
@@ -0,0 +1,301 @@
+/** @file
+  This file defines the PCH SPI Protocol which implements the
+  Intel(R) PCH SPI Host Controller Compatibility Interface.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_SPI_PROTOCOL_H_
+#define _PCH_SPI_PROTOCOL_H_
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID                   gPchSpiProtocolGuid;
+extern EFI_GUID                   gPchSmmSpiProtocolGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _PCH_SPI_PROTOCOL  PCH_SPI_PROTOCOL;
+
+//
+// SPI protocol data structures and definitions
+//
+
+/**
+  Flash Region Type
+**/
+typedef enum {
+  FlashRegionDescriptor,
+  FlashRegionBios,
+  FlashRegionMe,
+  FlashRegionGbE,
+  FlashRegionPlatformData,
+  FlashRegionDer,
+  FlashRegionSecondaryBios,
+  FlashRegionuCodePatch,
+  FlashRegionEC,
+  FlashRegionDeviceExpansion2,
+  FlashRegionIE,
+  FlashRegion10Gbe_A,
+  FlashRegion10Gbe_B,
+  FlashRegion13,
+  FlashRegion14,
+  FlashRegion15,
+  FlashRegionAll,
+  FlashRegionMax
+} FLASH_REGION_TYPE;
+//
+// Protocol member functions
+//
+
+/**
+  Read data from the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] FlashRegionType      The Flash Region type for flash cycle which is listed in the Descriptor.
+  @param[in] Address              The Flash Linear Address must fall within a region for which BIOS has access permissions.
+  @param[in] ByteCount            Number of bytes in the data portion of the SPI cycle.
+  @param[out] Buffer              The Pointer to caller-allocated buffer containing the dada received.
+                                  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_READ) (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     FLASH_REGION_TYPE  FlashRegionType,
+  IN     UINT32             Address,
+  IN     UINT32             ByteCount,
+  OUT    UINT8              *Buffer
+  );
+
+/**
+  Write data to the flash part. Remark: Erase may be needed before write to the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] FlashRegionType      The Flash Region type for flash cycle which is listed in the Descriptor.
+  @param[in] Address              The Flash Linear Address must fall within a region for which BIOS has access permissions.
+  @param[in] ByteCount            Number of bytes in the data portion of the SPI cycle.
+  @param[in] Buffer               Pointer to caller-allocated buffer containing the data sent during the SPI cycle.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_WRITE) (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     FLASH_REGION_TYPE  FlashRegionType,
+  IN     UINT32             Address,
+  IN     UINT32             ByteCount,
+  IN     UINT8              *Buffer
+  );
+
+/**
+  Erase some area on the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] FlashRegionType      The Flash Region type for flash cycle which is listed in the Descriptor.
+  @param[in] Address              The Flash Linear Address must fall within a region for which BIOS has access permissions.
+  @param[in] ByteCount            Number of bytes in the data portion of the SPI cycle.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_ERASE) (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     FLASH_REGION_TYPE  FlashRegionType,
+  IN     UINT32             Address,
+  IN     UINT32             ByteCount
+  );
+
+/**
+  Read SFDP data from the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] ComponentNumber      The Componen Number for chip select
+  @param[in] Address              The starting byte address for SFDP data read.
+  @param[in] ByteCount            Number of bytes in SFDP data portion of the SPI cycle
+  @param[out] SfdpData            The Pointer to caller-allocated buffer containing the SFDP data received
+                                  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_READ_SFDP) (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT8              ComponentNumber,
+  IN     UINT32             Address,
+  IN     UINT32             ByteCount,
+  OUT    UINT8              *SfdpData
+  );
+
+/**
+  Read Jedec Id from the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] ComponentNumber      The Componen Number for chip select
+  @param[in] ByteCount            Number of bytes in JedecId data portion of the SPI cycle, the data size is 3 typically
+  @param[out] JedecId             The Pointer to caller-allocated buffer containing JEDEC ID received
+                                  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_READ_JEDEC_ID) (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT8              ComponentNumber,
+  IN     UINT32             ByteCount,
+  OUT    UINT8              *JedecId
+  );
+
+/**
+  Write the status register in the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] ByteCount            Number of bytes in Status data portion of the SPI cycle, the data size is 1 typically
+  @param[in] StatusValue          The Pointer to caller-allocated buffer containing the value of Status register writing
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_WRITE_STATUS) (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT32             ByteCount,
+  IN     UINT8              *StatusValue
+  );
+
+/**
+  Read status register in the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] ByteCount            Number of bytes in Status data portion of the SPI cycle, the data size is 1 typically
+  @param[out] StatusValue         The Pointer to caller-allocated buffer containing the value of Status register received.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_FLASH_READ_STATUS) (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT32             ByteCount,
+  OUT    UINT8              *StatusValue
+  );
+
+/**
+  Get the SPI region base and size, based on the enum type
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] FlashRegionType      The Flash Region type for for the base address which is listed in the Descriptor.
+  @param[out] BaseAddress         The Flash Linear Address for the Region 'n' Base
+  @param[out] RegionSize          The size for the Region 'n'
+
+  @retval EFI_SUCCESS             Read success
+  @retval EFI_INVALID_PARAMETER   Invalid region type given
+  @retval EFI_DEVICE_ERROR        The region is not used
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_GET_REGION_ADDRESS) (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     FLASH_REGION_TYPE  FlashRegionType,
+  OUT    UINT32             *BaseAddress,
+  OUT    UINT32             *RegionSize
+  );
+
+/**
+  Read PCH Soft Strap Values
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] SoftStrapAddr        PCH Soft Strap address offset from FPSBA.
+  @param[in] ByteCount            Number of bytes in SoftStrap data portion of the SPI cycle
+  @param[out] SoftStrapValue      The Pointer to caller-allocated buffer containing PCH Soft Strap Value.
+                                  If the value of ByteCount is 0, the data type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Soft Strap Length
+                                  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_READ_PCH_SOFTSTRAP) (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT32             SoftStrapAddr,
+  IN     UINT32             ByteCount,
+  OUT    VOID               *SoftStrapValue
+  );
+
+/**
+  Read CPU Soft Strap Values
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] SoftStrapAddr        CPU Soft Strap address offset from FCPUSBA.
+  @param[in] ByteCount            Number of bytes in SoftStrap data portion of the SPI cycle.
+  @param[out] SoftStrapValue      The Pointer to caller-allocated buffer containing CPU Soft Strap Value.
+                                  If the value of ByteCount is 0, the data type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Soft Strap Length
+                                  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SPI_READ_CPU_SOFTSTRAP) (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT32             SoftStrapAddr,
+  IN     UINT32             ByteCount,
+  OUT    VOID               *SoftStrapValue
+  );
+
+/**
+  These protocols/PPI allows a platform module to perform SPI operations through the
+  Intel PCH SPI Host Controller Interface.
+**/
+struct _PCH_SPI_PROTOCOL {
+  /**
+    This member specifies the revision of this structure. This field is used to
+    indicate backwards compatible changes to the protocol.
+  **/
+  UINT8                             Revision;
+  PCH_SPI_FLASH_READ                FlashRead;          ///< Read data from the flash part.
+  PCH_SPI_FLASH_WRITE               FlashWrite;         ///< Write data to the flash part. Remark: Erase may be needed before write to the flash part.
+  PCH_SPI_FLASH_ERASE               FlashErase;         ///< Erase some area on the flash part.
+  PCH_SPI_FLASH_READ_SFDP           FlashReadSfdp;      ///< Read SFDP data from the flash part.
+  PCH_SPI_FLASH_READ_JEDEC_ID       FlashReadJedecId;   ///< Read Jedec Id from the flash part.
+  PCH_SPI_FLASH_WRITE_STATUS        FlashWriteStatus;   ///< Write the status register in the flash part.
+  PCH_SPI_FLASH_READ_STATUS         FlashReadStatus;    ///< Read status register in the flash part.
+  PCH_SPI_GET_REGION_ADDRESS        GetRegionAddress;   ///< Get the SPI region base and size
+  PCH_SPI_READ_PCH_SOFTSTRAP        ReadPchSoftStrap;   ///< Read PCH Soft Strap Values
+  PCH_SPI_READ_CPU_SOFTSTRAP        ReadCpuSoftStrap;   ///< Read CPU Soft Strap Values
+};
+
+/**
+  PCH SPI PPI/PROTOCOL revision number
+
+  Revision 1:   Initial version
+**/
+#define PCH_SPI_SERVICES_REVISION       1
+
+#endif
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 03/40] TigerlakeSiliconPkg/Include: Add Pins, Register and other include headers
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
  2021-02-05  7:40 ` [Patch V3 02/40] TigerlakeSiliconPkg/Include: Add Library, PPI and Protocol include headers Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 04/40] TigerlakeSiliconPkg/Cpu: Add Include headers Heng Luo
                   ` (36 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following header files:
  * Include/Pins
  * Include/Register
  * Include/*.h

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock.h            |  53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/CpuPcieHob.h             |  38 ++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/DmaRemappingTable.h      |  75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/DxeHdaNhlt.h             | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Hda.h                    |  57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/MePolicyCommon.h         |  24 ++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/PcieRegs.h               | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Pins/GpioPinsVer2Lp.h    | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Register/FlashRegs.h     |  72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Register/GpioRegs.h      | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Register/GpioRegsVer2.h  | 226 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Register/PchDmi14Regs.h  |  16 ++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Register/PchDmiRegs.h    |  36 ++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Register/PchPcieRpRegs.h |  93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Register/PmcRegs.h       | 258 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Register/RtcRegs.h       |  45 +++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Register/SataRegs.h      |  56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Register/SerialIoRegs.h  |  47 +++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/Register/UsbRegs.h       |  51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/SerialIoDevices.h        | 213 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/SiConfigHob.h            |  17 +++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Include/SiPolicyStruct.h         |  64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 22 files changed, 1965 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock.h
new file mode 100644
index 0000000000..ad34e4ea42
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/ConfigBlock.h
@@ -0,0 +1,53 @@
+/** @file
+  Header file for Config Block Lib implementation
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CONFIG_BLOCK_H_
+#define _CONFIG_BLOCK_H_
+
+#include <Uefi/UefiBaseType.h>
+#include <Uefi/UefiMultiPhase.h>
+#include <Pi/PiBootMode.h>
+#include <Pi/PiHob.h>
+
+#pragma pack (push,1)
+
+///
+/// Config Block Header
+///
+typedef struct _CONFIG_BLOCK_HEADER {
+  EFI_HOB_GUID_TYPE GuidHob;                      ///< Offset 0-23  GUID extension HOB header
+  UINT8             Revision;                     ///< Offset 24    Revision of this config block
+  UINT8             Attributes;                   ///< Offset 25    The main revision for config block
+  UINT8             Reserved[2];                  ///< Offset 26-27 Reserved for future use
+} CONFIG_BLOCK_HEADER;
+
+///
+/// Config Block
+///
+typedef struct _CONFIG_BLOCK {
+  CONFIG_BLOCK_HEADER            Header;          ///< Offset 0-27  Header of config block
+  //
+  // Config Block Data
+  //
+} CONFIG_BLOCK;
+
+///
+/// Config Block Table Header
+///
+typedef struct _CONFIG_BLOCK_TABLE_STRUCT {
+  CONFIG_BLOCK_HEADER            Header;          ///< Offset 0-27  GUID number for main entry of config block
+  UINT8                          Rsvd0[2];        ///< Offset 28-29 Reserved for future use
+  UINT16                         NumberOfBlocks;  ///< Offset 30-31 Number of config blocks (N)
+  UINT32                         AvailableSize;   ///< Offset 32-35 Current config block table size
+///
+/// Individual Config Block Structures are added here in memory as part of AddConfigBlock()
+///
+} CONFIG_BLOCK_TABLE_HEADER;
+#pragma pack (pop)
+
+#endif // _CONFIG_BLOCK_H_
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/CpuPcieHob.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/CpuPcieHob.h
new file mode 100644
index 0000000000..23a408e8dc
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/CpuPcieHob.h
@@ -0,0 +1,38 @@
+/** @file
+  The GUID definition for CpuPcieHob
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _CPU_PCIE_HOB_H_
+#define _CPU_PCIE_HOB_H_
+
+#include <Base.h>
+#include <CpuPcieInfo.h>
+#include <CpuPcieConfig.h>
+
+extern EFI_GUID gCpuPcieHobGuid;
+#pragma pack (push,1)
+
+/**
+  The CPU_PCIE_HOB block describes the expected configuration of the CpuPcie controllers
+**/
+typedef struct {
+  ///
+  /// These members describe the configuration of each CPU PCIe root port.
+  ///
+  EFI_HOB_GUID_TYPE           EfiHobGuidType;                           ///< Offset 0 - 23: GUID Hob type structure for gCpuPcieHobGuid
+  CPU_PCIE_ROOT_PORT_CONFIG   RootPort[CPU_PCIE_MAX_ROOT_PORTS];
+  UINT8                       L1SubStates[CPU_PCIE_MAX_ROOT_PORTS];  ///< The L1 Substates configuration of the root port
+
+  UINT32                      DekelFwVersionMinor;                      ///< Dekel Firmware Minor Version
+  UINT32                      DekelFwVersionMajor;                      ///< Dekel Firmware Major Version
+  BOOLEAN                     InitPcieAspmAfterOprom;                   ///< 1=initialize PCIe ASPM after Oprom; 0=before (This will be set basing on policy)
+  UINT32                      RpEnabledMask;                            ///< Rootport enabled mask based on DEVEN register
+  UINT32                      RpEnMaskFromDevEn;                        ///< Rootport enabled mask based on Device Id
+  UINT8                       DisableClkReqMsg[CPU_PCIE_MAX_ROOT_PORTS];     ///< 1=ClkReqMsg disabled, 0=ClkReqMsg enabled
+  UINT8                       SlotSelection;                            ///< 1=M2 slot, 0=CEMx4 slot
+  BOOLEAN                     ComplianceTest;                           ///< Compliance Test based on policy
+} CPU_PCIE_HOB;
+#pragma pack (pop)
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/DmaRemappingTable.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/DmaRemappingTable.h
new file mode 100644
index 0000000000..5b058c7a45
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/DmaRemappingTable.h
@@ -0,0 +1,75 @@
+/** @file
+  This code defines ACPI DMA Remapping table related definitions.
+  See the System Agent BIOS specification for definition of the table.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _DMA_REMAPPING_TABLE_H_
+#define _DMA_REMAPPING_TABLE_H_
+
+#include <Uefi.h>
+#include <Base.h>
+#include <IndustryStandard/DmaRemappingReportingTable.h>
+#include <IndustryStandard/Acpi.h>
+#include <TcssInfo.h>
+
+#pragma pack(1)
+///
+/// DMAR table signature
+///
+#define EFI_ACPI_VTD_DMAR_TABLE_SIGNATURE   0x52414D44  ///< "DMAR"
+#define EFI_ACPI_DMAR_TABLE_REVISION        2
+#define EFI_ACPI_DRHD_ENGINE_HEADER_LENGTH  0x10
+#define EFI_ACPI_RMRR_HEADER_LENGTH         0x18
+#define MAX_PCI_DEPTH                       5
+
+typedef struct {
+  EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER DeviceScopeStructureHeader;
+  EFI_ACPI_DMAR_PCI_PATH                      PciPath;     // device, function
+} EFI_ACPI_DEV_SCOPE_STRUCTURE;
+
+typedef struct {
+  EFI_ACPI_DMAR_DRHD_HEADER     DrhdHeader;
+  EFI_ACPI_DEV_SCOPE_STRUCTURE  DeviceScope[1];
+} EFI_ACPI_DRHD_ENGINE1_STRUCT;
+
+typedef struct {
+  EFI_ACPI_DMAR_DRHD_HEADER     DrhdHeader;
+  //
+  // @todo use PCD
+  //
+  EFI_ACPI_DEV_SCOPE_STRUCTURE  DeviceScope[2];
+} EFI_ACPI_DRHD_ENGINE3_STRUCT;
+
+typedef struct {
+  EFI_ACPI_DMAR_RMRR_HEADER     RmrrHeader;
+  EFI_ACPI_DEV_SCOPE_STRUCTURE  DeviceScope[2];
+} EFI_ACPI_RMRR_USB_STRUC;
+
+typedef struct {
+  EFI_ACPI_DMAR_RMRR_HEADER     RmrrHeader;
+  EFI_ACPI_DEV_SCOPE_STRUCTURE  DeviceScope[1];    // IGD
+} EFI_ACPI_RMRR_IGD_STRUC;
+
+typedef struct {
+  EFI_ACPI_DMAR_RMRR_HEADER     RmrrHeader;
+  EFI_ACPI_DEV_SCOPE_STRUCTURE  DeviceScope[1];    // IGD - DiSM
+} EFI_ACPI_RMRR_IGD_DISM_STRUC;
+
+typedef struct {
+  EFI_ACPI_DMAR_ANDD_HEADER     AnddHeader;
+  UINT8                         AcpiObjectName[20];
+} EFI_ACPI_ANDD_STRUC;
+
+typedef struct {
+  EFI_ACPI_DMAR_HEADER          DmarHeader;
+  EFI_ACPI_DRHD_ENGINE1_STRUCT  DrhdEngine1;
+  EFI_ACPI_DRHD_ENGINE3_STRUCT  DrhdEngine3;
+  EFI_ACPI_RMRR_IGD_STRUC       RmrrIgd;
+  EFI_ACPI_RMRR_IGD_DISM_STRUC  RmrrIgdDism;
+} EFI_ACPI_DMAR_TABLE;
+
+#pragma pack()
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/DxeHdaNhlt.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/DxeHdaNhlt.h
new file mode 100644
index 0000000000..edb3855b68
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/DxeHdaNhlt.h
@@ -0,0 +1,138 @@
+/** @file
+  Header file for DxePchHdaNhltLib - NHLT structure definitions.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _DXE_HDA_NHLT_H_
+#define _DXE_HDA_NHLT_H_
+
+#include <IndustryStandard/Acpi.h>
+
+//
+// ACPI support protocol instance signature definition.
+//
+#define NHLT_ACPI_TABLE_SIGNATURE  SIGNATURE_32 ('N', 'H', 'L', 'T')
+
+// MSFT defined structures
+#define SPEAKER_FRONT_LEFT      0x1
+#define SPEAKER_FRONT_RIGHT     0x2
+#define SPEAKER_FRONT_CENTER    0x4
+#define SPEAKER_BACK_LEFT       0x10
+#define SPEAKER_BACK_RIGHT      0x20
+
+#define KSAUDIO_SPEAKER_MONO   (SPEAKER_FRONT_CENTER)
+#define KSAUDIO_SPEAKER_STEREO (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT)
+#define KSAUDIO_SPEAKER_QUAD   (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT)
+
+#define WAVE_FORMAT_EXTENSIBLE    0xFFFE /* Microsoft */
+#define KSDATAFORMAT_SUBTYPE_PCM \
+        {0x00000001, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}
+
+#pragma pack (push, 1)
+
+typedef struct {
+  UINT16  wFormatTag;
+  UINT16  nChannels;
+  UINT32  nSamplesPerSec;
+  UINT32  nAvgBytesPerSec;
+  UINT16  nBlockAlign;
+  UINT16  wBitsPerSample;
+  UINT16  cbSize;
+} WAVEFORMATEX;
+
+typedef struct {
+  WAVEFORMATEX Format;
+  union {
+    UINT16 wValidBitsPerSample;
+    UINT16 wSamplesPerBlock;
+    UINT16 wReserved;
+  } Samples;
+  UINT32       dwChannelMask;
+  GUID         SubFormat;
+} WAVEFORMATEXTENSIBLE;
+
+//
+// List of supported link type.
+//
+enum NHLT_LINK_TYPE
+{
+  HdaNhltLinkHd   = 0,
+  HdaNhltLinkDsp  = 1,
+  HdaNhltLinkDmic = 2,
+  HdaNhltLinkSsp  = 3,
+  HdaNhltLinkInvalid
+};
+
+//
+// List of supported device type.
+//
+enum NHLT_SSP_DEVICE_TYPE
+{
+  HdaNhltSspDeviceBt   = 0,
+  HdaNhltSspDeviceI2s  = 4,
+  HdaNhltSspDeviceInvalid
+};
+
+enum NHLT_PDM_DEVICE_TYPE
+{
+  HdaNhltPdmDeviceDmic = 0,
+  HdaNhltPdmDeviceInvalid
+};
+
+typedef struct {
+  UINT32    CapabilitiesSize;
+  UINT8     Capabilities[1];
+} SPECIFIC_CONFIG;
+
+typedef struct {
+  WAVEFORMATEXTENSIBLE Format;
+  SPECIFIC_CONFIG      FormatConfiguration;
+} FORMAT_CONFIG;
+
+typedef struct {
+  UINT8           FormatsCount;
+  FORMAT_CONFIG   FormatsConfiguration[1];
+} FORMATS_CONFIG;
+
+typedef struct {
+  UINT8           DeviceId[16];
+  UINT8           DeviceInstanceId;
+  UINT8           DevicePortId;
+} DEVICE_INFO;
+
+typedef struct {
+  UINT8           DeviceInfoCount;
+  DEVICE_INFO     DeviceInformation[1];
+} DEVICES_INFO;
+
+typedef struct {
+  UINT32          EndpointDescriptorLength;
+  UINT8           LinkType;
+  UINT8           InstanceId;
+  UINT16          HwVendorId;
+  UINT16          HwDeviceId;
+  UINT16          HwRevisionId;
+  UINT32          HwSubsystemId;
+  UINT8           DeviceType;
+  UINT8           Direction;
+  UINT8           VirtualBusId;
+  SPECIFIC_CONFIG EndpointConfig;
+  FORMATS_CONFIG  FormatsConfig;
+  DEVICES_INFO    DevicesInformation;
+} ENDPOINT_DESCRIPTOR;
+
+//
+// High Level Table structure
+//
+typedef struct {
+  EFI_ACPI_DESCRIPTION_HEADER Header; //{'N', 'H', 'L', 'T'}
+  UINT8                       EndpointCount;   // Actual number of endpoints
+  ENDPOINT_DESCRIPTOR         EndpointDescriptors[1];
+  SPECIFIC_CONFIG             OedConfiguration;
+} NHLT_ACPI_TABLE;
+
+#pragma pack (pop)
+
+#endif // _DXE_PCH_HDA_NHLT_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Hda.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Hda.h
new file mode 100644
index 0000000000..ab3f2c9cd0
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Hda.h
@@ -0,0 +1,57 @@
+/** @file
+  Header file for HD Audio configuration.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _HDA_H_
+#define _HDA_H_
+
+typedef enum {
+  HdaVc0 = 0,
+  HdaVc1 = 1
+} HDAUDIO_VC_TYPE;
+
+typedef enum {
+  HdaDmicDisabled = 0,
+  HdaDmic2chArray = 1,
+  HdaDmic4chArray = 2,
+  HdaDmic1chArray = 3
+} HDAUDIO_DMIC_TYPE;
+
+typedef enum {
+  HdaLinkFreq6MHz  = 0,
+  HdaLinkFreq12MHz = 1,
+  HdaLinkFreq24MHz = 2,
+  HdaLinkFreq48MHz = 3,
+  HdaLinkFreq96MHz = 4,
+  HdaLinkFreqInvalid
+} HDAUDIO_LINK_FREQUENCY;
+
+typedef enum  {
+  HdaIDispMode2T  = 0,
+  HdaIDispMode1T  = 1,
+  HdaIDispMode4T  = 2,
+  HdaIDispMode8T  = 3,
+  HdaIDispMode16T = 4,
+  HdaIDispTModeInvalid
+} HDAUDIO_IDISP_TMODE;
+
+typedef enum {
+  HdaLink      = 0,
+  HdaIDispLink = 1,
+  HdaDmic      = 2,
+  HdaSsp       = 3,
+  HdaSndw      = 4,
+  HdaLinkUnsupported
+} HDAUDIO_LINK_TYPE;
+
+typedef enum {
+  HdaDmicClockSelectBoth = 0,
+  HdaDmicClockSelectClkA = 1,
+  HdaDmicClockSelectClkB = 2,
+  HdaDmicClockSelectInvalid
+} HDAUDIO_DMIC_CLOCK_SELECT;
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/MePolicyCommon.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/MePolicyCommon.h
new file mode 100644
index 0000000000..023ba12daa
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/MePolicyCommon.h
@@ -0,0 +1,24 @@
+/** @file
+  Definition for ME common policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _ME_POLICY_COMMON_H_
+#define _ME_POLICY_COMMON_H_
+
+#include <ConfigBlock.h>
+
+#include <MePeiConfig.h>
+
+#ifndef PLATFORM_POR
+#define PLATFORM_POR  0
+#endif
+#ifndef FORCE_ENABLE
+#define FORCE_ENABLE  1
+#endif
+#ifndef FORCE_DISABLE
+#define FORCE_DISABLE 2
+#endif
+
+#endif // _ME_POLICY_COMMON_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/PcieRegs.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/PcieRegs.h
new file mode 100644
index 0000000000..d98019d1b4
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/PcieRegs.h
@@ -0,0 +1,155 @@
+/** @file
+  Register names for PCIE standard register
+
+  Conventions:
+
+  - Prefixes:
+    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 sizes
+    Definitions beginning with "N_" are the bit position
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCIE_REGS_H_
+#define _PCIE_REGS_H_
+
+#include <IndustryStandard/Pci30.h>
+
+//
+// PCI type 0 Header
+//
+#define R_PCI_BCC_OFFSET                          0x0B
+
+//
+// PCI type 1 Header
+//
+#define R_PCI_BRIDGE_BNUM                         0x18 ///< Bus Number Register
+#define B_PCI_BRIDGE_BNUM_SBBN                    0x00FF0000 ///< Subordinate Bus Number
+#define B_PCI_BRIDGE_BNUM_SCBN                    0x0000FF00 ///< Secondary Bus Number
+
+//
+// PCI Express Capability List Register (CAPID:10h)
+//
+#define R_PCIE_XCAP_OFFSET                        0x02 ///< PCI Express Capabilities Register (Offset 02h)
+#define B_PCIE_XCAP_DT                            (BIT7 | BIT6 | BIT5 | BIT4) ///< Device/Port Type
+#define N_PCIE_XCAP_DT                            4
+
+#define R_PCIE_DCAP_OFFSET                        0x04 ///< Device Capabilities Register (Offset 04h)
+#define B_PCIE_DCAP_RBER                          BIT15 ///< Role-Based Error Reporting
+#define B_PCIE_DCAP_E1AL                          (BIT11 | BIT10 | BIT9) ///< Endpoint L1 Acceptable Latency
+#define N_PCIE_DCAP_E1AL                          9
+#define B_PCIE_DCAP_E0AL                          (BIT8 | BIT7 | BIT6) ///< Endpoint L0s Acceptable Latency
+#define N_PCIE_DCAP_E0AL                          6
+#define B_PCIE_DCAP_MPS                           (BIT2 | BIT1 | BIT0) ///< Max_Payload_Size Supported
+
+#define R_PCIE_DCTL_OFFSET                        0x08 ///< Device Control Register (Offset 08h)
+#define B_PCIE_DCTL_MPS                           (BIT7 | BIT6 | BIT5) ///< Max_Payload_Size
+#define N_PCIE_DCTL_MPS                           5
+
+#define R_PCIE_LCAP_OFFSET                        0x0C ///< Link Capabilities Register (Offset 0Ch)
+#define B_PCIE_LCAP_CPM                           BIT18 ///< Clock Power Management
+#define B_PCIE_LCAP_EL1                           (BIT17 | BIT16 | BIT15) ///< L1 Exit Latency
+#define N_PCIE_LCAP_EL1                           15
+#define B_PCIE_LCAP_EL0                           (BIT14 | BIT13 | BIT12) ///< L0s Exit Latency
+#define N_PCIE_LCAP_EL0                           12
+#define B_PCIE_LCAP_APMS_L0S                      BIT10
+#define B_PCIE_LCAP_APMS_L1                       BIT11
+#define B_PCIE_LCAP_MLS                           (BIT3 | BIT2 | BIT1 | BIT0) ///< Max Link Speed
+#define V_PCIE_LCAP_MLS_GEN3                      3
+#define V_PCIE_LCAP_MLS_GEN4                      4
+
+#define R_PCIE_LCTL_OFFSET                        0x10 ///< Link Control Register (Offset 10h)
+#define B_PCIE_LCTL_ECPM                          BIT8 ///< Enable Clock Power Management
+#define B_PCIE_LCTL_CCC                           BIT6 ///< Common Clock Configuration
+#define B_PCIE_LCTL_RL                            BIT5 ///< Retrain Link
+#define B_PCIE_LCTL_ASPM                          (BIT1 | BIT0) ///< Active State Power Management (ASPM) Control
+#define V_PCIE_LCTL_ASPM_L0S                      1
+#define V_PCIE_LCTL_ASPM_L1                       2
+#define V_PCIE_LCTL_ASPM_L0S_L1                   3
+
+#define R_PCIE_LSTS_OFFSET                        0x12 ///< Link Status Register (Offset 12h)
+#define B_PCIE_LSTS_LA                            BIT13 ///< Data Link Layer Link Active
+#define B_PCIE_LSTS_SCC                           BIT12 ///< Slot Clock Configuration
+#define B_PCIE_LSTS_LT                            BIT11 ///< Link Training
+#define B_PCIE_LSTS_NLW                           0x03F0 ///< Negotiated Link Width
+#define N_PCIE_LSTS_NLW                           4
+#define B_PCIE_LSTS_CLS                           0x000F ///< Current Link Speed
+
+#define R_PCIE_SLCAP_OFFSET                       0x14 ///< Slot Capabilities Register (Offset 14h)
+#define B_PCIE_SLCAP_HPC                          BIT6       ///< Hot-Plug Capable
+
+#define R_PCIE_SLSTS_OFFSET                       0x1A ///< Slot Status Register (Offset 1Ah)
+#define B_PCIE_SLSTS_PDS                          BIT6 ///< Presence Detect State
+
+#define R_PCIE_DCAP2_OFFSET                       0x24 ///< Device Capabilities 2 Register (Offset 24h)
+#define B_PCIE_DCAP2_LTRMS                        BIT11 ///< LTR Mechanism Supported
+
+#define R_PCIE_DCTL2_OFFSET                       0x28 ///< Device Control 2 Register (Offset 28h)
+#define B_PCIE_DCTL2_LTREN                        BIT10 ///< LTR Mechanism Enable
+
+#define B_PCIE_LCTL2_TLS                          (BIT3 | BIT2 | BIT1 | BIT0) ///< Target Link Speed
+
+//
+// Latency Tolerance Reporting Extended Capability Registers (CAPID:0018h)
+//
+#define R_PCIE_LTRECH_CID                         0x0018
+
+#define R_PCIE_LTRECH_MSLR_OFFSET                 0x04
+#define N_PCIE_LTRECH_MSLR_VALUE                  0
+#define N_PCIE_LTRECH_MSLR_SCALE                  10
+
+#define R_PCIE_LTRECH_MNSLR_OFFSET                0x06
+#define N_PCIE_LTRECH_MNSLR_VALUE                 0
+#define N_PCIE_LTRECH_MNSLR_SCALE                 10
+
+//
+// Secondary PCI Express Extended Capability Header (CAPID:0019h)
+//
+#define R_PCIE_EX_LCTL3_OFFSET                    0x04 ///< Link Control 3 Register
+#define B_PCIE_EX_LCTL3_PE                        BIT0 ///< Perform Equalization
+
+//
+// L1 Sub-States Extended Capability Register (CAPID:001Eh)
+//
+#define V_PCIE_EX_L1S_CID                        0x001E ///< Capability ID
+#define R_PCIE_EX_L1SCAP_OFFSET                  0x04 ///< L1 Sub-States Capabilities
+#define B_PCIE_EX_L1SCAP_PTV                     0x00F80000 //< Port Tpower_on value
+#define N_PCIE_EX_L1SCAP_PTV                     19
+#define B_PCIE_EX_L1SCAP_PTPOS                   0x00030000 //< Port Tpower_on scale
+#define N_PCIE_EX_L1SCAP_PTPOS                   16
+#define B_PCIE_EX_L1SCAP_CMRT                    0x0000FF00 //< Common Mode Restore time
+#define N_PCIE_EX_L1SCAP_CMRT                    8
+#define B_PCIE_EX_L1SCAP_L1PSS                   BIT4 ///< L1 PM substates supported
+#define B_PCIE_EX_L1SCAP_AL1SS                   BIT3 ///< ASPM L1.1 supported
+#define B_PCIE_EX_L1SCAP_AL12S                   BIT2 ///< ASPM L1.2 supported
+#define B_PCIE_EX_L1SCAP_PPL11S                  BIT1 ///< PCI-PM L1.1 supported
+#define B_PCIE_EX_L1SCAP_PPL12S                  BIT0 ///< PCI-PM L1.2 supported
+#define R_PCIE_EX_L1SCTL1_OFFSET                 0x08 ///< L1 Sub-States Control 1
+#define B_PCIE_EX_L1SCTL1_L1SSEIE                BIT4
+#define N_PCIE_EX_L1SCTL1_L12LTRTLSV             29
+#define N_PCIE_EX_L1SCTL1_L12LTRTLV              16
+#define R_PCIE_EX_L1SCTL2_OFFSET                 0x0C ///< L1 Sub-States Control 2
+#define N_PCIE_EX_L1SCTL2_POWT                   3
+
+//
+// PTM Extended Capability Register (CAPID:001Fh)
+//
+#define V_PCIE_EX_PTM_CID                         0x001F ///< Capability ID
+#define R_PCIE_EX_PTMCAP_OFFSET                   0x04 ///< PTM Capabilities
+#define R_PCIE_EX_PTMCTL_OFFSET                   0x08 ///< PTM Control Register
+
+//
+// Base Address Offset
+//
+#define B_PCI_BAR_MEMORY_TYPE_MASK                (BIT1 | BIT2)
+#define B_PCI_BAR_MEMORY_TYPE_64                  BIT2
+
+//
+// PCI Express Extended Capability Header
+//
+#define R_PCIE_CFG_EXCAP_OFFSET                   0x100
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Pins/GpioPinsVer2Lp.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Pins/GpioPinsVer2Lp.h
new file mode 100644
index 0000000000..ef94790985
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Pins/GpioPinsVer2Lp.h
@@ -0,0 +1,110 @@
+/** @file
+  GPIO pins for TGL-PCH-LP,
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _GPIO_PINS_VER2_LP_H_
+#define _GPIO_PINS_VER2_LP_H_
+///
+/// This header file should be used together with
+/// PCH GPIO lib in C and ASL. All defines used
+/// must match both ASL/C syntax
+///
+
+///
+/// Unique ID used in GpioPad defines
+///
+#define GPIO_VER2_LP_CHIPSET_ID     0x9
+
+///
+/// TGL LP GPIO Groups
+/// Use below for functions from PCH GPIO Lib which
+/// require GpioGroup as argument
+///
+#define GPIO_VER2_LP_GROUP_GPP_B    0x0900
+#define GPIO_VER2_LP_GROUP_GPP_A    0x0902
+#define GPIO_VER2_LP_GROUP_GPP_R    0x0903
+#define GPIO_VER2_LP_GROUP_GPD      0x0905
+#define GPIO_VER2_LP_GROUP_GPP_S    0x0906
+#define GPIO_VER2_LP_GROUP_GPP_H    0x0907
+#define GPIO_VER2_LP_GROUP_GPP_D    0x0908
+#define GPIO_VER2_LP_GROUP_GPP_C    0x090B
+#define GPIO_VER2_LP_GROUP_GPP_F    0x090C
+#define GPIO_VER2_LP_GROUP_GPP_E    0x090E
+
+
+///
+/// TGL LP GPIO pins
+/// Use below for functions from PCH GPIO Lib which
+/// require GpioPad as argument. Encoding used here
+/// has all information required by library functions
+///
+#define GPIO_VER2_LP_GPP_B2                  0x09000002
+#define GPIO_VER2_LP_GPP_B4                  0x09000004
+#define GPIO_VER2_LP_GPP_B14                 0x0900000E
+#define GPIO_VER2_LP_GPP_B15                 0x0900000F
+#define GPIO_VER2_LP_GPP_B16                 0x09000010
+#define GPIO_VER2_LP_GPP_B18                 0x09000012
+#define GPIO_VER2_LP_GPP_B23                 0x09000017
+#define GPIO_VER2_LP_GSPI0_CLK_LOOPBK        0x09000018
+
+#define GPIO_VER2_LP_GPP_A10                 0x0902000A
+#define GPIO_VER2_LP_GPP_A11                 0x0902000B
+#define GPIO_VER2_LP_GPP_A13                 0x0902000D
+#define GPIO_VER2_LP_GPP_A14                 0x0902000E
+#define GPIO_VER2_LP_GPP_A23                 0x09020017
+#define GPIO_VER2_LP_ESPI_CLK_LOOPBK         0x09020018
+
+#define GPIO_VER2_LP_GPP_R5                  0x09030005
+#define GPIO_VER2_LP_GPP_R6                  0x09030006
+
+#define GPIO_VER2_LP_GPD7                    0x09050007
+
+#define GPIO_VER2_LP_INPUT3VSEL              0x0905000C
+
+#define GPIO_VER2_LP_GPP_H0                  0x09070000
+#define GPIO_VER2_LP_GPP_H1                  0x09070001
+#define GPIO_VER2_LP_GPP_H12                 0x0907000C
+#define GPIO_VER2_LP_GPP_H13                 0x0907000D
+#define GPIO_VER2_LP_GPP_H15                 0x0907000F
+#define GPIO_VER2_LP_GPP_H19                 0x09070013
+
+#define GPIO_VER2_LP_GPP_D16                 0x09080010
+#define GPIO_VER2_LP_GSPI2_CLK_LOOPBK        0x09080014
+
+#define GPIO_VER2_LP_GPP_C2                  0x090B0002
+#define GPIO_VER2_LP_GPP_C5                  0x090B0005
+#define GPIO_VER2_LP_GPP_C8                  0x090B0008
+#define GPIO_VER2_LP_GPP_C12                 0x090B000C
+#define GPIO_VER2_LP_GPP_C13                 0x090B000D
+#define GPIO_VER2_LP_GPP_C14                 0x090B000E
+#define GPIO_VER2_LP_GPP_C15                 0x090B000F
+#define GPIO_VER2_LP_GPP_C22                 0x090B0016
+#define GPIO_VER2_LP_GPP_C23                 0x090B0017
+
+#define GPIO_VER2_LP_GPP_F4                  0x090C0004
+#define GPIO_VER2_LP_GPP_F5                  0x090C0005
+#define GPIO_VER2_LP_GPP_F9                  0x090C0009
+#define GPIO_VER2_LP_GPP_F10                 0x090C000A
+#define GPIO_VER2_LP_GPP_F20                 0x090C0014
+#define GPIO_VER2_LP_GPP_F21                 0x090C0015
+#define GPIO_VER2_LP_GPPF_CLK_LOOPBK         0x090C0018
+
+#define GPIO_VER2_LP_GPP_E3                  0x090E0003
+#define GPIO_VER2_LP_GPP_E7                  0x090E0007
+#define GPIO_VER2_LP_GPP_E8                  0x090E0008
+#define GPIO_VER2_LP_GPP_E22                 0x090E0016
+#define GPIO_VER2_LP_GPP_E23                 0x090E0017
+#define GPIO_VER2_LP_GPPE_CLK_LOOPBK         0x090E0018
+
+//
+// GPIO Pin Muxing
+// Determines a selection of physical pad for a given signal.
+// Please refer to GPIO_NATIVE_PAD type.
+// If certain signal is not listed below it means that it can be enabled
+// only on a single pad and muxing setting is not needed.
+//
+#define GPIO_VER2_LP_MUXING_SERIALIO_I2C4_SDA_GPP_H8         0x1947CC08
+#define GPIO_VER2_LP_MUXING_SERIALIO_I2C4_SCL_GPP_H9         0x1947AC09
+#endif // _GPIO_PINS_VER2_LP_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/FlashRegs.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/FlashRegs.h
new file mode 100644
index 0000000000..215fd0407e
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/FlashRegs.h
@@ -0,0 +1,72 @@
+/** @file
+  Register names for Flash registers
+
+  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 _FLASH_REGS_H_
+#define _FLASH_REGS_H_
+
+//
+// Flash Descriptor Base Address Region (FDBAR) from Flash Region 0
+//
+#define R_FLASH_FDBAR_FLASH_MAP0          0x04
+#define B_FLASH_FDBAR_NC                  0x00000300                    ///< Number Of Components
+#define N_FLASH_FDBAR_NC                  8                             ///< Number Of Components
+#define R_FLASH_FDBAR_FLASH_MAP1          0x08
+#define B_FLASH_FDBAR_FPSBA               0x00FF0000                    ///< PCH Strap Base Address, [23:16] represents [11:4]
+#define N_FLASH_FDBAR_FPSBA               16                            ///< PCH Strap base Address bit position
+#define N_FLASH_FDBAR_FPSBA_REPR          4                             ///< PCH Strap base Address bit represents position
+#define B_FLASH_FDBAR_PCHSL               0xFF000000                    ///< PCH Strap Length, [31:24] represents number of Dwords
+#define N_FLASH_FDBAR_PCHSL               24                            ///< PCH Strap Length bit position
+#define R_FLASH_FDBAR_FLASH_MAP2          0x0C
+#define B_FLASH_FDBAR_FCPUSBA             0x00000FFC                    ///< CPU Strap Base Address [11:2]
+#define N_FLASH_FDBAR_FCPUSBA             2                             ///< CPU Strap Base Address bit position
+#define B_FLASH_FDBAR_CPUSL               0x00FF0000                    ///< CPU Strap Length, [23:16] represents number of Dwords
+#define N_FLASH_FDBAR_CPUSL               16                            ///< CPU Strap Length bit position
+
+//
+// Flash Component Base Address (FCBA) from Flash Region 0
+//
+#define R_FLASH_FCBA_FLCOMP               0x00                          ///< Flash Components Register
+#define B_FLASH_FLCOMP_COMP1_MASK         0xF0                          ///< Flash Component 1 Size MASK
+#define N_FLASH_FLCOMP_COMP1              4                             ///< Flash Component 1 Size bit position
+#define B_FLASH_FLCOMP_COMP0_MASK         0x0F                          ///< Flash Component 0 Size MASK
+#define V_FLASH_FLCOMP_COMP_512KB         0x80000
+//
+// Descriptor Upper Map Section from Flash Region 0
+//
+#define R_FLASH_UMAP1                     0xEFC                         ///< Flash Upper Map 1
+#define B_FLASH_UMAP1_MDTBA               0xFF000000                    ///< MIP Descriptor Table Base Address
+#define N_FLASH_UMAP1_MDTBA               24                            ///< MDTBA bits position
+#define N_FLASH_UMAP1_MDTBA_REPR          4                             ///< MDTBA address representation position
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/GpioRegs.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/GpioRegs.h
new file mode 100644
index 0000000000..e4bf2018b7
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/GpioRegs.h
@@ -0,0 +1,121 @@
+/** @file
+  Register names for PCH GPIO
+
+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 _GPIO_REGS_H_
+#define _GPIO_REGS_H_
+
+//
+// PADCFG register is split into multiple DW registers
+// S_GPIO_PCR_PADCFG refers to number of bytes used by all those registers for one pad
+//
+#define S_GPIO_PCR_PADCFG               0x10
+
+//
+// Pad Configuration Register DW0
+//
+
+//Pad Reset Config
+#define B_GPIO_PCR_RST_CONF             (BIT31 | BIT30)
+#define N_GPIO_PCR_RST_CONF             30
+#define V_GPIO_PCR_RST_CONF_POW_GOOD    0x00
+#define V_GPIO_PCR_RST_CONF_DEEP_RST    0x01
+#define V_GPIO_PCR_RST_CONF_GPIO_RST    0x02
+#define V_GPIO_PCR_RST_CONF_RESUME_RST  0x03  // Only for GPD Group
+
+//RX Raw Override to 1
+#define B_GPIO_PCR_RX_RAW1              BIT28
+#define N_GPIO_PCR_RX_RAW1              28
+
+//RX Level/Edge Configuration
+#define B_GPIO_PCR_RX_LVL_EDG           (BIT26 | BIT25)
+#define N_GPIO_PCR_RX_LVL_EDG           25
+
+//RX Invert
+#define B_GPIO_PCR_RXINV                BIT23
+#define N_GPIO_PCR_RXINV                23
+
+//GPIO Input Route IOxAPIC
+#define B_GPIO_PCR_RX_APIC_ROUTE        BIT20
+
+//GPIO Input Route SCI
+#define B_GPIO_PCR_RX_SCI_ROUTE         BIT19
+
+//GPIO Input Route SMI
+#define B_GPIO_PCR_RX_SMI_ROUTE         BIT18
+
+//GPIO Input Route NMI
+#define B_GPIO_PCR_RX_NMI_ROUTE         BIT17
+#define N_GPIO_PCR_RX_NMI_ROUTE         17
+
+//GPIO Pad Mode
+#define B_GPIO_PCR_PAD_MODE             (BIT12 | BIT11 | BIT10)
+#define N_GPIO_PCR_PAD_MODE             10
+
+//GPIO RX Disable
+#define B_GPIO_PCR_RXDIS                BIT9
+
+//GPIO TX Disable
+#define B_GPIO_PCR_TXDIS                BIT8
+#define N_GPIO_PCR_TXDIS                8
+
+//GPIO RX State
+#define B_GPIO_PCR_RX_STATE             BIT1
+#define N_GPIO_PCR_RX_STATE             1
+
+//GPIO TX State
+#define B_GPIO_PCR_TX_STATE             BIT0
+#define N_GPIO_PCR_TX_STATE             0
+
+//Termination
+#define B_GPIO_PCR_TERM                (BIT13 | BIT12 | BIT11 | BIT10)
+#define N_GPIO_PCR_TERM                 10
+
+//Interrupt number
+#define B_GPIO_PCR_INTSEL               0x7F
+#define N_GPIO_PCR_INTSEL               0
+
+///
+/// GPIO SMI data used for EFI_SMM_GPI_DISPATCH2_PROTOCOL
+/// Below defines are to be used internally by PCH SMI dispatcher only
+///
+#define PCH_GPIO_NUM_SUPPORTED_GPIS       512
+#define S_GPIO_PCR_GP_SMI_STS               4
+
+///
+/// Groups mapped to 2-tier General Purpose Event will all be under
+/// one master GPE_111 (0x6F)
+///
+#define PCH_GPIO_2_TIER_MASTER_GPE_NUMBER  0x6F
+
+#endif // _GPIO_REGS_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/GpioRegsVer2.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/GpioRegsVer2.h
new file mode 100644
index 0000000000..1dc05869dd
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/GpioRegsVer2.h
@@ -0,0 +1,226 @@
+/** @file
+  Register names for VER2 GPIO
+
+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 _GPIO_REGS_VER2_H_
+#define _GPIO_REGS_VER2_H_
+
+//
+// PCH-LP GPIO
+//
+#define GPIO_VER2_PCH_LP_GPIO_GPP_B_PAD_MAX    26
+#define GPIO_VER2_PCH_LP_GPIO_GPP_A_PAD_MAX    25
+#define GPIO_VER2_PCH_LP_GPIO_GPP_R_PAD_MAX    8
+#define GPIO_VER2_PCH_LP_GPIO_GPD_PAD_MAX      17
+#define GPIO_VER2_PCH_LP_GPIO_GPP_S_PAD_MAX    8
+#define GPIO_VER2_PCH_LP_GPIO_GPP_H_PAD_MAX    24
+#define GPIO_VER2_PCH_LP_GPIO_GPP_D_PAD_MAX    21
+#define GPIO_VER2_PCH_LP_GPIO_GPP_F_PAD_MAX    25
+#define GPIO_VER2_PCH_LP_GPIO_GPP_C_PAD_MAX    24
+#define GPIO_VER2_PCH_LP_GPIO_GPP_E_PAD_MAX    25
+#define GPIO_VER2_PCH_LP_GPIO_CPU_PAD_MAX      15
+
+//
+// PCH-LP GPIO registers
+//
+
+//
+// GPIO Community 0 Private Configuration Registers
+//
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_PAD_OWN        0x20
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_PAD_OWN        0x38
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_PADCFGLOCK     0x80
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_PADCFGLOCKTX   0x84
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_PADCFGLOCK     0x90
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_PADCFGLOCKTX   0x94
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_HOSTSW_OWN     0xB0
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_HOSTSW_OWN     0xB8
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_GPI_IS         0x0100
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_GPI_IS         0x0108
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_GPI_IE         0x0120
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_GPI_IE         0x0128
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_GPI_GPE_STS    0x0140
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_GPI_GPE_STS    0x0148
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_GPI_GPE_EN     0x0160
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_GPI_GPE_EN     0x0168
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_SMI_STS        0x0180
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_SMI_EN         0x01A0
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_NMI_STS        0x01C0
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_NMI_EN         0x01E0
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_PADCFG_OFFSET  0x700
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_PADCFG_OFFSET  0x9A0
+
+//
+// GPIO Community 1 Private Configuration Registers
+//
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_PAD_OWN        0x20
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_PAD_OWN        0x24
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_PAD_OWN        0x30
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_PADCFGLOCK     0x80
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_PADCFGLOCKTX   0x84
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_PADCFGLOCK     0x88
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_PADCFGLOCKTX   0x8C
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_PADCFGLOCK     0x90
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_PADCFGLOCKTX   0x94
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_HOSTSW_OWN     0xB0
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_HOSTSW_OWN     0xB4
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_HOSTSW_OWN     0xB8
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_GPI_IS         0x0100
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_GPI_IS         0x0104
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_GPI_IS         0x0108
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_GPI_IE         0x0120
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_GPI_IE         0x0124
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_GPI_IE         0x0128
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_GPI_GPE_STS    0x0140
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_GPI_GPE_STS    0x0144
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_GPI_GPE_STS    0x0148
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_GPI_GPE_EN     0x0160
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_GPI_GPE_EN     0x0164
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_GPI_GPE_EN     0x0168
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_SMI_STS        0x0188
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_SMI_EN         0x01A8
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_NMI_STS        0x01C8
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_NMI_EN         0x01E8
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_PADCFG_OFFSET  0x700
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_PADCFG_OFFSET  0x780
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_PADCFG_OFFSET  0x900
+
+//
+// GPIO Community 2 Private Configuration Registers
+//
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_PAD_OWN          0x20
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_PADCFGLOCK       0x80
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_PADCFGLOCKTX     0x84
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_HOSTSW_OWN       0xB0
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_GPI_IS           0x0100
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_GPI_IE           0x0120
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_GPI_GPE_STS      0x0140
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_GPI_GPE_EN       0x0160
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_PADCFG_OFFSET    0x700
+
+//
+// GPIO Community 4 Private Configuration Registers
+//
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_PAD_OWN        0x20
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_PAD_OWN        0x2C
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_PAD_OWN        0x40
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_PADCFGLOCK     0x80
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_PADCFGLOCKTX   0x84
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_PADCFGLOCK     0x88
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_PADCFGLOCKTX   0x8C
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_PADCFGLOCK     0x98
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_PADCFGLOCKTX   0x9C
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_HOSTSW_OWN     0xB0
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_HOSTSW_OWN     0xB4
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_HOSTSW_OWN     0xBC
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_GPI_IS         0x0100
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_GPI_IS         0x0104
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_GPI_IS         0x010C
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_GPI_IE         0x0120
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_GPI_IE         0x0124
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_GPI_IE         0x012C
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_GPI_GPE_STS    0x0140
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_GPI_GPE_STS    0x0144
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_GPI_GPE_STS    0x014C
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_GPI_GPE_EN     0x0160
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_GPI_GPE_EN     0x0164
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_GPI_GPE_EN     0x016C
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_SMI_STS        0x0180
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_SMI_STS        0x018C
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_SMI_EN         0x01A0
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_SMI_EN         0x01AC
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_NMI_STS        0x01C0
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_NMI_STS        0x01CC
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_NMI_EN         0x01E0
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_NMI_EN         0x01EC
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_PADCFG_OFFSET  0x700
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_PADCFG_OFFSET  0x880
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_PADCFG_OFFSET  0xA70
+
+//
+// GPIO Community 5 Private Configuration Registers
+//
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_PAD_OWN        0x20
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_PADCFGLOCK     0x80
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_PADCFGLOCKTX   0x84
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_HOSTSW_OWN     0xB0
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_GPI_IS         0x0100
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_GPI_IE         0x0120
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_GPI_GPE_STS    0x0140
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_GPI_GPE_EN     0x0160
+
+#define R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_PADCFG_OFFSET  0x700
+
+#endif // _GPIO_REGS_VER2_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/PchDmi14Regs.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/PchDmi14Regs.h
new file mode 100644
index 0000000000..5447fabccf
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/PchDmi14Regs.h
@@ -0,0 +1,16 @@
+/** @file
+  Register names for PCH DMI SIP14
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_DMI14_REGS_H_
+#define _PCH_DMI14_REGS_H_
+
+//
+// DMI Control
+//
+#define R_PCH_DMI14_PCR_DMIC                       0x2234                              ///< DMI Control
+#define B_PCH_DMI14_PCR_DMIC_SRL                   BIT31                               ///< Secured register lock
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/PchDmiRegs.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/PchDmiRegs.h
new file mode 100644
index 0000000000..e9e6f80327
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/PchDmiRegs.h
@@ -0,0 +1,36 @@
+/** @file
+  Register names for PCH DMI and OP-DMI
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_DMI_REGS_H_
+#define _PCH_DMI_REGS_H_
+
+//
+// PCH DMI Chipset Configuration Registers (PID:DMI)
+//
+
+//
+// PCH DMI Source Decode PCRs (Common)
+//
+#define R_PCH_DMI_PCR_LPCLGIR1                   0x2730                       ///< LPC Generic I/O Range 1
+#define R_PCH_DMI_PCR_LPCGMR                     0x2740                       ///< LPC Generic Memory Range
+#define R_PCH_DMI_PCR_SEGIR                      0x27BC                       ///< Second ESPI Generic I/O Range
+#define R_PCH_DMI_PCR_SEGMR                      0x27C0                       ///< Second ESPI Generic Memory Range
+#define R_PCH_DMI_PCR_LPCBDE                     0x2744                       ///< LPC BIOS Decode Enable
+#define R_PCH_DMI_PCR_UCPR                       0x2748                       ///< uCode Patch Region
+#define B_PCH_DMI_PCR_UCPR_UPRE                  BIT0                         ///< uCode Patch Region Enable
+#define R_PCH_DMI_PCR_GCS                        0x274C                       ///< Generic Control and Status
+#define B_PCH_DMI_PCR_BBS                        BIT10                        ///< Boot BIOS Strap
+#define B_PCH_DMI_PCR_RPR                        BIT11                        ///< Reserved Page Route
+#define B_PCH_DMI_PCR_BILD                       BIT0                         ///< BIOS Interface Lock-Down
+#define R_PCH_DMI_PCR_IOT1                       0x2750                       ///< I/O Trap Register 1
+#define R_PCH_DMI_PCR_LPCIOD                     0x2770                       ///< LPC I/O Decode Ranges
+#define R_PCH_DMI_PCR_LPCIOE                     0x2774                       ///< LPC I/O Enables
+#define R_PCH_DMI_PCR_TCOBASE                    0x2778                       ///< TCO Base Address
+#define B_PCH_DMI_PCR_TCOBASE_TCOBA              0xFFE0                       ///< TCO Base Address Mask
+#define R_PCH_DMI_PCR_GPMR1                      0x277C                       ///< General Purpose Memory Range 1
+#define R_PCH_DMI_PCR_GPMR1DID                   0x2780                       ///< General Purpose Memory Range 1 Destination ID
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/PchPcieRpRegs.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/PchPcieRpRegs.h
new file mode 100644
index 0000000000..c3497b1013
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/PchPcieRpRegs.h
@@ -0,0 +1,93 @@
+/** @file
+  Register names for PCH PCI-E root port devices
+
+  Conventions:
+
+  - Register definition format:
+    Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpace_RegisterName
+  - Prefix:
+    Definitions beginning with "R_" are registers
+    Definitions beginning with "B_" are bits within registers
+    Definitions beginning with "V_" are meaningful values within the bits
+    Definitions beginning with "S_" are register size
+    Definitions beginning with "N_" are the bit position
+  - [GenerationName]:
+    Three letter acronym of the generation is used (e.g. SKL,KBL,CNL etc.).
+    Register name without GenerationName applies to all generations.
+  - [ComponentName]:
+    This field indicates the component name that the register belongs to (e.g. PCH, SA etc.)
+    Register name without ComponentName applies to all components.
+    Register that is specific to -LP denoted by "_PCH_LP_" in component name.
+  - SubsystemName:
+    This field indicates the subsystem name of the component that the register belongs to
+    (e.g. PCIE, USB, SATA, GPIO, PMC etc.).
+  - RegisterSpace:
+    MEM - MMIO space register of subsystem.
+    IO  - IO space register of subsystem.
+    PCR - Private configuration register of subsystem.
+    CFG - PCI configuration space register of subsystem.
+  - RegisterName:
+    Full register name.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_REGS_PCIE_H_
+#define _PCH_REGS_PCIE_H_
+
+#define R_PCH_PCIE_CFG_CLIST                          0x40
+#define R_PCH_PCIE_CFG_LCAP                           (R_PCH_PCIE_CFG_CLIST + R_PCIE_LCAP_OFFSET)
+#define N_PCH_PCIE_CFG_LCAP_PN                        24
+#define R_PCH_PCIE_CFG_LCTL                           (R_PCH_PCIE_CFG_CLIST + R_PCIE_LCTL_OFFSET)
+#define R_PCH_PCIE_CFG_LSTS                           (R_PCH_PCIE_CFG_CLIST + R_PCIE_LSTS_OFFSET)
+#define R_PCH_PCIE_CFG_SLCAP                          (R_PCH_PCIE_CFG_CLIST + R_PCIE_SLCAP_OFFSET)
+#define R_PCH_PCIE_CFG_SLSTS                          (R_PCH_PCIE_CFG_CLIST + R_PCIE_SLSTS_OFFSET)
+
+#define R_PCH_PCIE_CFG_MPC2                           0xD4
+#define B_PCH_PCIE_CFG_MPC2_EOIFD                     BIT1
+
+#define R_PCH_PCIE_CFG_MPC                            0xD8
+#define S_PCH_PCIE_CFG_MPC                            4
+#define B_PCH_PCIE_CFG_MPC_PMCE                       BIT31
+#define B_PCH_PCIE_CFG_MPC_HPME                       BIT1
+#define N_PCH_PCIE_CFG_MPC_HPME                       1
+
+#define R_PCH_PCIE_CFG_SMSCS                          0xDC
+#define S_PCH_PCIE_CFG_SMSCS                          4
+#define B_PCH_PCIE_CFG_SMSCS_PMCS                     BIT31
+#define N_PCH_PCIE_CFG_SMSCS_LERSMIS                  5
+#define N_PCH_PCIE_CFG_SMSCS_HPLAS                    4
+#define N_PCH_PCIE_CFG_SMSCS_HPPDM                    1
+
+//CES.RE, CES.BT, CES.BD
+
+#define R_PCH_PCIE_CFG_EX_SPEECH                      0xA30 ///< Secondary PCI Express Extended Capability Header
+#define R_PCH_PCIE_CFG_EX_LCTL3                       (R_PCH_PCIE_CFG_EX_SPEECH + R_PCIE_EX_LCTL3_OFFSET)
+
+#define R_PCH_PCIE_CFG_LTROVR                         0x400
+#define B_PCH_PCIE_CFG_LTROVR_LTRNSROVR               BIT31 ///< LTR Non-Snoop Requirement Bit Override
+#define B_PCH_PCIE_CFG_LTROVR_LTRSROVR                BIT15 ///< LTR Snoop Requirement Bit Override
+
+#define R_PCH_PCIE_CFG_LTROVR2                        0x404
+#define B_PCH_PCIE_CFG_LTROVR2_FORCE_OVERRIDE         BIT3 ///< LTR Force Override Enable
+#define B_PCH_PCIE_CFG_LTROVR2_LOCK                   BIT2 ///< LTR Override Lock
+#define B_PCH_PCIE_CFG_LTROVR2_LTRNSOVREN             BIT1 ///< LTR Non-Snoop Override Enable
+#define B_PCH_PCIE_CFG_LTROVR2_LTRSOVREN              BIT0 ///< LTR Snoop Override Enable
+
+#define R_PCH_PCIE_CFG_PCIEPMECTL                     0x420
+#define B_PCH_PCIE_CFG_PCIEPMECTL_DLSULPPGE           BIT30
+#define B_PCH_PCIE_CFG_PCIEPMECTL_L1LE                BIT17
+#define B_PCH_PCIE_CFG_PCIEPMECTL_L1FSOE              BIT0
+
+#define R_PCH_PCIE_CFG_EQCFG1                         0x450
+#define S_PCH_PCIE_CFG_EQCFG1                         4
+#define N_PCH_PCIE_CFG_EQCFG1_LERSMIE                 21
+
+//
+// PCIE PCRs (PID:SPA SPB SPC SPD SPE SPF)
+//
+#define R_SPX_PCR_PCD                         0                       ///< Port configuration and disable
+#define B_SPX_PCR_PCD_RP1FN                   (BIT2 | BIT1 | BIT0)    ///< Port 1 Function Number
+#define S_SPX_PCR_PCD_RP_FIELD                4                       ///< 4 bits for each RP FN
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/PmcRegs.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/PmcRegs.h
new file mode 100644
index 0000000000..fac1497773
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/PmcRegs.h
@@ -0,0 +1,258 @@
+/** @file
+  Register names for PCH PMC device
+
+  Conventions:
+
+  - Register definition format:
+    Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpace_RegisterName
+  - Prefix:
+    Definitions beginning with "R_" are registers
+    Definitions beginning with "B_" are bits within registers
+    Definitions beginning with "V_" are meaningful values within the bits
+    Definitions beginning with "S_" are register size
+    Definitions beginning with "N_" are the bit position
+  - [GenerationName]:
+    Three letter acronym of the generation is used (e.g. SKL,KBL,CNL etc.).
+    Register name without GenerationName applies to all generations.
+  - [ComponentName]:
+    This field indicates the component name that the register belongs to (e.g. PCH, SA etc.)
+    Register name without ComponentName applies to all components.
+    Register that is specific to -LP denoted by "_PCH_LP_" in component name.
+  - SubsystemName:
+    This field indicates the subsystem name of the component that the register belongs to
+    (e.g. PCIE, USB, SATA, GPIO, PMC etc.).
+  - RegisterSpace:
+    MEM - MMIO space register of subsystem.
+    IO  - IO space register of subsystem.
+    PCR - Private configuration register of subsystem.
+    CFG - PCI configuration space register of subsystem.
+  - RegisterName:
+    Full register name.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_REGS_PMC_H_
+#define _PCH_REGS_PMC_H_
+
+//
+// ACPI and legacy I/O register offsets from ACPIBASE
+//
+#define R_ACPI_IO_PM1_STS                        0x00
+#define S_ACPI_IO_PM1_STS                        2
+#define B_ACPI_IO_PM1_STS_WAK                    BIT15
+#define B_ACPI_IO_PM1_STS_PCIEXP_WAKE_STS        BIT14
+#define B_ACPI_IO_PM1_STS_PRBTNOR                BIT11
+#define B_ACPI_IO_PM1_STS_RTC                    BIT10
+#define B_ACPI_IO_PM1_STS_PWRBTN                 BIT8
+#define B_ACPI_IO_PM1_STS_GBL                    BIT5
+#define B_ACPI_IO_PM1_STS_TMROF                  BIT0
+#define N_ACPI_IO_PM1_STS_RTC                    10
+#define N_ACPI_IO_PM1_STS_PWRBTN                 8
+#define N_ACPI_IO_PM1_STS_TMROF                  0
+
+#define R_ACPI_IO_PM1_EN                         0x02
+#define S_ACPI_IO_PM1_EN                         2
+#define B_ACPI_IO_PM1_EN_PWRBTN                  BIT8
+#define N_ACPI_IO_PM1_EN_RTC                     10
+#define N_ACPI_IO_PM1_EN_PWRBTN                  8
+#define N_ACPI_IO_PM1_EN_TMROF                   0
+
+#define R_ACPI_IO_PM1_CNT                        0x04
+#define B_ACPI_IO_PM1_CNT_SLP_EN                 BIT13
+#define B_ACPI_IO_PM1_CNT_SLP_TYP                (BIT12 | BIT11 | BIT10)
+#define V_ACPI_IO_PM1_CNT_S0                     0
+#define V_ACPI_IO_PM1_CNT_S1                     BIT10
+#define V_ACPI_IO_PM1_CNT_S3                     (BIT12 | BIT10)
+#define V_ACPI_IO_PM1_CNT_S4                     (BIT12 | BIT11)
+#define V_ACPI_IO_PM1_CNT_S5                     (BIT12 | BIT11 | BIT10)
+#define B_ACPI_IO_PM1_CNT_SCI_EN                 BIT0
+
+#define R_ACPI_IO_PM1_TMR                        0x08
+#define B_ACPI_IO_PM1_TMR_VAL                    0xFFFFFF
+#define V_ACPI_IO_PM1_TMR_MAX_VAL                0x1000000       ///< The timer is 24 bit overflow
+
+#define R_ACPI_IO_SMI_EN                              0x30
+#define S_ACPI_IO_SMI_EN                              4
+#define B_ACPI_IO_SMI_EN_LEGACY_USB2                  BIT17
+#define B_ACPI_IO_SMI_EN_TCO                          BIT13
+#define B_ACPI_IO_SMI_EN_BIOS_RLS                     BIT7
+#define B_ACPI_IO_SMI_EN_SWSMI_TMR                    BIT6
+#define B_ACPI_IO_SMI_EN_APMC                         BIT5
+#define B_ACPI_IO_SMI_EN_LEGACY_USB                   BIT3
+#define B_ACPI_IO_SMI_EN_BIOS                         BIT2
+#define B_ACPI_IO_SMI_EN_EOS                          BIT1
+#define B_ACPI_IO_SMI_EN_GBL_SMI                      BIT0
+#define N_ACPI_IO_SMI_EN_LEGACY_USB3                  31
+#define N_ACPI_IO_SMI_EN_ESPI                         28
+#define N_ACPI_IO_SMI_EN_PERIODIC                     14
+#define N_ACPI_IO_SMI_EN_TCO                          13
+#define N_ACPI_IO_SMI_EN_MCSMI                        11
+#define N_ACPI_IO_SMI_EN_SWSMI_TMR                    6
+#define N_ACPI_IO_SMI_EN_APMC                         5
+#define N_ACPI_IO_SMI_EN_ON_SLP_EN                    4
+#define N_ACPI_IO_SMI_EN_LEGACY_USB                   3
+
+#define R_ACPI_IO_SMI_STS                             0x34
+#define S_ACPI_IO_SMI_STS                             4
+#define B_ACPI_IO_SMI_STS_GPIO_UNLOCK                 BIT27
+#define B_ACPI_IO_SMI_STS_SMBUS                       BIT16
+#define B_ACPI_IO_SMI_STS_PERIODIC                    BIT14
+#define B_ACPI_IO_SMI_STS_TCO                         BIT13
+#define B_ACPI_IO_SMI_STS_MCSMI                       BIT11
+#define B_ACPI_IO_SMI_STS_SWSMI_TMR                   BIT6
+#define B_ACPI_IO_SMI_STS_APM                         BIT5
+#define B_ACPI_IO_SMI_STS_ON_SLP_EN                   BIT4
+#define B_ACPI_IO_SMI_STS_BIOS                        BIT2
+#define N_ACPI_IO_SMI_STS_LEGACY_USB3                 31
+#define N_ACPI_IO_SMI_STS_ESPI                        28
+#define N_ACPI_IO_SMI_STS_SPI                         26
+#define N_ACPI_IO_SMI_STS_MONITOR                     21
+#define N_ACPI_IO_SMI_STS_PCI_EXP                     20
+#define N_ACPI_IO_SMI_STS_SMBUS                       16
+#define N_ACPI_IO_SMI_STS_SERIRQ                      15
+#define N_ACPI_IO_SMI_STS_PERIODIC                    14
+#define N_ACPI_IO_SMI_STS_TCO                         13
+#define N_ACPI_IO_SMI_STS_MCSMI                       11
+#define N_ACPI_IO_SMI_STS_GPIO_SMI                    10
+#define N_ACPI_IO_SMI_STS_GPE0                        9
+#define N_ACPI_IO_SMI_STS_PM1_STS_REG                 8
+#define N_ACPI_IO_SMI_STS_SWSMI_TMR                   6
+#define N_ACPI_IO_SMI_STS_APM                         5
+#define N_ACPI_IO_SMI_STS_ON_SLP_EN                   4
+#define N_ACPI_IO_SMI_STS_LEGACY_USB                  3
+
+#define R_ACPI_IO_DEVACT_STS                          0x44
+#define B_ACPI_IO_DEVACT_STS_KBC                      BIT12
+#define B_ACPI_IO_DEVACT_STS_PIRQDH                   BIT9
+#define B_ACPI_IO_DEVACT_STS_PIRQCG                   BIT8
+#define B_ACPI_IO_DEVACT_STS_PIRQBF                   BIT7
+#define B_ACPI_IO_DEVACT_STS_PIRQAE                   BIT6
+
+#define R_ACPI_IO_GPE0_STS_127_96                  0x6C
+#define S_ACPI_IO_GPE0_STS_127_96                  4
+#define B_ACPI_IO_GPE0_STS_127_96_WADT             BIT18
+#define B_ACPI_IO_GPE0_STS_127_96_USB_CON_DSX_STS  BIT17
+#define B_ACPI_IO_GPE0_STS_127_96_LAN_WAKE         BIT16
+#define B_ACPI_IO_GPE0_STS_127_96_PME_B0           BIT13
+#define B_ACPI_IO_GPE0_STS_127_96_PME              BIT11
+#define B_ACPI_IO_GPE0_STS_127_96_BATLOW           BIT10
+#define B_ACPI_IO_GPE0_STS_127_96_RI               BIT8
+#define B_ACPI_IO_GPE0_STS_127_96_SMB_WAK          BIT7
+#define B_ACPI_IO_GPE0_STS_127_96_SWGPE            BIT2
+#define N_ACPI_IO_GPE0_STS_127_96_PME_B0           13
+#define N_ACPI_IO_GPE0_STS_127_96_PME              11
+
+#define R_ACPI_IO_GPE0_EN_127_96                   0x7C
+#define S_ACPI_IO_GPE0_EN_127_96                   4
+#define B_ACPI_IO_GPE0_EN_127_96_WADT              BIT18
+#define B_ACPI_IO_GPE0_EN_127_96_LAN_WAKE          BIT16
+#define B_ACPI_IO_GPE0_EN_127_96_PME_B0            BIT13
+#define B_ACPI_IO_GPE0_EN_127_96_ME_SCI            BIT12
+#define B_ACPI_IO_GPE0_EN_127_96_PME               BIT11
+#define B_ACPI_IO_GPE0_EN_127_96_BATLOW            BIT10
+#define B_ACPI_IO_GPE0_EN_127_96_RI                BIT8
+#define B_ACPI_IO_GPE0_EN_127_96_SWGPE             BIT2
+#define N_ACPI_IO_GPE0_EN_127_96_PME_B0            13
+#define N_ACPI_IO_GPE0_EN_127_96_PME               11
+
+//
+// TCO register I/O map
+//
+#define R_TCO_IO_TCO1_STS                            0x04
+#define S_TCO_IO_TCO1_STS                            2
+#define B_TCO_IO_TCO1_STS_DMISERR                    BIT12
+#define B_TCO_IO_TCO1_STS_DMISMI                     BIT10
+#define B_TCO_IO_TCO1_STS_DMISCI                     BIT9
+#define B_TCO_IO_TCO1_STS_BIOSWR                     BIT8
+#define B_TCO_IO_TCO1_STS_NEWCENTURY                 BIT7
+#define B_TCO_IO_TCO1_STS_TIMEOUT                    BIT3
+#define B_TCO_IO_TCO1_STS_TCO_INT                    BIT2
+#define B_TCO_IO_TCO1_STS_SW_TCO_SMI                 BIT1
+#define N_TCO_IO_TCO1_STS_DMISMI                     10
+#define N_TCO_IO_TCO1_STS_BIOSWR                     8
+#define N_TCO_IO_TCO1_STS_NEWCENTURY                 7
+#define N_TCO_IO_TCO1_STS_TIMEOUT                    3
+#define N_TCO_IO_TCO1_STS_SW_TCO_SMI                 1
+#define N_TCO_IO_TCO1_STS_NMI2SMI                    0
+
+#define R_TCO_IO_TCO2_STS                            0x06
+#define S_TCO_IO_TCO2_STS                            2
+#define B_TCO_IO_TCO2_STS_SECOND_TO                  BIT1
+#define B_TCO_IO_TCO2_STS_INTRD_DET                  BIT0
+#define N_TCO_IO_TCO2_STS_INTRD_DET                  0
+
+#define R_TCO_IO_TCO1_CNT                            0x08
+#define S_TCO_IO_TCO1_CNT                            2
+#define B_TCO_IO_TCO1_CNT_LOCK                       BIT12
+#define N_TCO_IO_TCO1_CNT_NMI2SMI_EN                 9
+
+#define R_TCO_IO_TCO2_CNT                            0x0A
+#define S_TCO_IO_TCO2_CNT                            2
+#define N_TCO_IO_TCO2_CNT_INTRD_SEL                  2
+
+//
+// PWRM Registers
+//
+#define R_PMC_PWRM_GEN_PMCON_A                              0x1020                        ///< in CNL located in PWRM
+#define B_PMC_PWRM_GEN_PMCON_A_GBL_RST_STS                  BIT24
+#define B_PMC_PWRM_GEN_PMCON_A_DISB                         BIT23
+#define B_PMC_PWRM_GEN_PMCON_A_ALLOW_L1LOW_C0               BIT19
+#define B_PMC_PWRM_GEN_PMCON_A_MS4V                         BIT18
+#define B_PMC_PWRM_GEN_PMCON_A_SUS_PWR_FLR                  BIT16
+#define B_PMC_PWRM_GEN_PMCON_A_PWR_FLR                      BIT14
+#define B_PMC_PWRM_GEN_PMCON_A_HOST_RST_STS                 BIT9
+#define B_PMC_PWRM_GEN_PMCON_A_ESPI_SMI_LOCK                BIT8
+#define B_PMC_PWRM_GEN_PMCON_A_AFTERG3_EN                   BIT0
+#define B_PMC_PWRM_GEN_PMCON_A_SWSMI_RTSL                   0xC0
+#define V_PMC_PWRM_GEN_PMCON_A_SWSMI_RTSL_64MS              0xC0
+#define V_PMC_PWRM_GEN_PMCON_A_SWSMI_RTSL_32MS              0x80
+#define V_PMC_PWRM_GEN_PMCON_A_SWSMI_RTSL_16MS              0x40
+#define V_PMC_PWRM_GEN_PMCON_A_SWSMI_RTSL_1_5MS             0x00
+#define B_PMC_PWRM_GEN_PMCON_A_PER_SMI_SEL                  0x6
+#define V_PMC_PWRM_GEN_PMCON_A_PER_SMI_64S                  0x0000
+#define V_PMC_PWRM_GEN_PMCON_A_PER_SMI_32S                  0x0002
+#define V_PMC_PWRM_GEN_PMCON_A_PER_SMI_16S                  0x0004
+#define V_PMC_PWRM_GEN_PMCON_A_PER_SMI_8S                   0x0006
+
+#define R_PMC_PWRM_GEN_PMCON_B                              0x1024
+#define B_PMC_PWRM_GEN_PMCON_B_SLPSX_STR_POL_LOCK           BIT18            ///< Lock down SLP_S3/SLP_S4 Minimum Assertion width
+#define B_PMC_PWRM_GEN_PMCON_B_PWRBTN_LVL                   BIT9
+#define B_PMC_PWRM_GEN_PMCON_B_SMI_LOCK                     BIT4
+#define B_PMC_PWRM_GEN_PMCON_B_RTC_PWR_STS                  BIT2
+
+#define R_PMC_PWRM_CRID                                     0x1030           ///< Configured Revision ID
+#define V_PMC_PWRM_CRID_RID_SEL_CRID0                       1
+#define B_PMC_PWRM_CRID_CRID_LK                             BIT31            ///< CRID Lock
+
+#define R_PMC_PWRM_ETR3                                     0x1048          ///< in CNL this is PWRM register
+#define B_PMC_PWRM_ETR3_CF9LOCK                             BIT31           ///< CF9h Lockdown
+#define B_PMC_PWRM_ETR3_CF9GR                               BIT20           ///< CF9h Global Reset
+#define B_PMC_PWRM_ETR3_CWORWRE                             BIT18
+
+#define R_PMC_PWRM_CFG                                      0x1818                      ///< Power Management Configuration
+#define B_PMC_PWRM_CFG_DBG_MODE_LOCK                        BIT27                       ///< Debug Mode Lock
+#define B_PMC_PWRM_CFG_PMCREAD_DISABLE                      BIT22                       ///< Disable Reads to PMC
+#define B_PMC_PWRM_CFG_TIMING_TPCH25                        (BIT1 | BIT0)               ///< tPCH25 timing
+
+#define R_PMC_PWRM_DSX_CFG                                  0x1834                      ///< Deep SX Configuration
+#define B_PMC_PWRM_DSX_CFG_LAN_WAKE_EN                      BIT0                        ///< LAN_WAKE Pin DeepSx Enable
+
+#define R_PMC_PWRM_GPIO_CFG                                 0x1920
+#define B_PMC_PWRM_GPIO_CFG_GPE0_DW2                        (BIT11 | BIT10 | BIT9 | BIT8)
+#define N_PMC_PWRM_GPIO_CFG_GPE0_DW2                        8
+#define B_PMC_PWRM_GPIO_CFG_GPE0_DW1                        (BIT7 | BIT6 | BIT5 | BIT4)
+#define N_PMC_PWRM_GPIO_CFG_GPE0_DW1                        4
+#define B_PMC_PWRM_GPIO_CFG_GPE0_DW0                        (BIT3 | BIT2 | BIT1 | BIT0)
+#define N_PMC_PWRM_GPIO_CFG_GPE0_DW0                        0
+
+#define R_PMC_PWRM_HPR_CAUSE0                               0x192C   ///< Host partition reset causes
+#define B_PMC_PWRM_HPR_CAUSE0_GBL_TO_HOST                   BIT15    ///< Global reset converted to Host reset
+
+#define R_PMC_PWRM_ST_PG_FDIS_PMC_1                         0x1E20 ///< Static PG Related Function Disable Register 1
+#define B_PMC_PWRM_ST_PG_FDIS_PMC_1_ST_FDIS_LK              BIT31 ///< Static Function Disable Lock (ST_FDIS_LK)
+
+#define R_PMC_PWRM_FUSE_DIS_RD_2                            0x1E44 ///< Fuse Disable Read 2 Register
+#define B_PMC_PWRM_FUSE_DIS_RD_2_GBE_FUSE_SS_DIS            BIT0  ///< GBE Fuse or Soft Strap Disable
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/RtcRegs.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/RtcRegs.h
new file mode 100644
index 0000000000..5824663d22
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/RtcRegs.h
@@ -0,0 +1,45 @@
+/** @file
+  Register names for RTC device
+
+Conventions:
+
+  - Register definition format:
+    Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpace_RegisterName
+  - Prefix:
+    Definitions beginning with "R_" are registers
+    Definitions beginning with "B_" are bits within registers
+    Definitions beginning with "V_" are meaningful values within the bits
+    Definitions beginning with "S_" are register size
+    Definitions beginning with "N_" are the bit position
+  - [GenerationName]:
+    Three letter acronym of the generation is used (e.g. SKL,KBL,CNL etc.).
+    Register name without GenerationName applies to all generations.
+  - [ComponentName]:
+    This field indicates the component name that the register belongs to (e.g. PCH, SA etc.)
+    Register name without ComponentName applies to all components.
+    Register that is specific to -LP denoted by "_PCH_LP_" in component name.
+  - SubsystemName:
+    This field indicates the subsystem name of the component that the register belongs to
+    (e.g. PCIE, USB, SATA, GPIO, PMC etc.).
+  - RegisterSpace:
+    MEM - MMIO space register of subsystem.
+    IO  - IO space register of subsystem.
+    PCR - Private configuration register of subsystem.
+    CFG - PCI configuration space register of subsystem.
+  - RegisterName:
+    Full register name.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _REGS_RTC_H_
+#define _REGS_RTC_H_
+
+#define R_RTC_IO_INDEX                           0x70
+#define R_RTC_IO_TARGET                          0x71
+#define R_RTC_IO_INDEX_ALT                       0x74
+#define R_RTC_IO_TARGET_ALT                      0x75
+#define R_RTC_IO_EXT_INDEX_ALT                   0x76
+#define R_RTC_IO_REGD                            0x0D
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/SataRegs.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/SataRegs.h
new file mode 100644
index 0000000000..2037bb003d
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/SataRegs.h
@@ -0,0 +1,56 @@
+/** @file
+  Register names for SATA controllers
+
+  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 _SATA_REGS_H_
+#define _SATA_REGS_H_
+
+//
+//  SATA Controller Common Registers
+//
+#define R_SATA_CFG_AHCI_BAR                 0x24
+#define R_SATA_CFG_MAP                      0x90
+#define N_SATA_CFG_MAP_SPD                  16
+#define R_SATA_CFG_PCS                      0x94
+#define B_SATA_CFG_PCS_P0P                  BIT16
+#define R_SATA_CFG_SATAGC                   0x9C
+#define B_SATA_CFG_SATAGC_ASSEL             (BIT2 | BIT1 | BIT0)
+#define V_SATA_CFG_SATAGC_ASSEL_2K          0x0
+#define V_SATA_CFG_SATAGC_ASSEL_16K         0x1
+#define V_SATA_CFG_SATAGC_ASSEL_32K         0x2
+#define V_SATA_CFG_SATAGC_ASSEL_64K         0x3
+#define V_SATA_CFG_SATAGC_ASSEL_128K        0x4
+#define V_SATA_CFG_SATAGC_ASSEL_256K        0x5
+#define V_SATA_CFG_SATAGC_ASSEL_512K        0x6
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/SerialIoRegs.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/SerialIoRegs.h
new file mode 100644
index 0000000000..9864dd872d
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/SerialIoRegs.h
@@ -0,0 +1,47 @@
+/** @file
+  Register names for Serial IO Controllers
+
+  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_H_
+#define _SERIAL_IO_REGS_H_
+
+//
+// Serial IO Controllers PCI Configuration Registers
+// registers accessed using PciD21FxRegBase + offset
+//
+#define R_SERIAL_IO_CFG_BAR0_LOW                            0x10
+#define R_SERIAL_IO_CFG_BAR0_HIGH                           0x14
+
+#define R_SERIAL_IO_CFG_PME_CTRL_STS                        0x84
+
+#endif //_SERIAL_IO_REGS_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/UsbRegs.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/UsbRegs.h
new file mode 100644
index 0000000000..ea832873bf
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/Register/UsbRegs.h
@@ -0,0 +1,51 @@
+/** @file
+  Register names for USB Host and device controller
+
+  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 _USB_REGS_H_
+#define _USB_REGS_H_
+
+//
+// XHCI PCI Config Space registers
+//
+#define R_XHCI_CFG_PWR_CNTL_STS             0x74
+#define B_XHCI_CFG_PWR_CNTL_STS_PWR_STS     (BIT1 | BIT0)
+#define V_XHCI_CFG_PWR_CNTL_STS_PWR_STS_D3  (BIT1 | BIT0)
+
+//
+// xDCI (OTG) MMIO registers
+//
+#define R_XDCI_MEM_GCTL                       0xC110  ///< Xdci Global Ctrl
+
+#endif // _USB_REGS_H_
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/SerialIoDevices.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/SerialIoDevices.h
new file mode 100644
index 0000000000..e2e1cf2ad2
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/SerialIoDevices.h
@@ -0,0 +1,213 @@
+/** @file
+  Serial IO policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SERIAL_IO_DEVICES_H_
+#define _SERIAL_IO_DEVICES_H_
+
+#include <Protocol/SerialIo.h>
+#include <PchLimits.h>
+
+#pragma pack (push,1)
+
+/**
+  Available working modes for SerialIo SPI Host Controller
+
+       0: SerialIoSpiDisabled;
+          - Device is placed in D3
+          - Gpio configuration is skipped
+          - PSF:
+          !important! If given device is Function 0 and other higher functions on given device
+                      are enabled, PSF disabling is skipped. PSF default will remain and device PCI CFG Space will still be visible.
+                      This is needed to allow PCI enumerator access functions above 0 in a multifunction device.
+    <b>1: SerialIoSpiPci;</b>
+          - Gpio pin configuration in native mode for each assigned pin
+          - Device will be enabled in PSF
+          - Only BAR0 will be enabled
+       2: SerialIoSpiHidden;
+          - Gpio pin configuration in native mode for each assigned pin
+          - Device disabled in the PSF
+          - Both BARs are enabled, BAR1 becomes devices Pci Config Space
+          - BAR0 assigned from the global PCH reserved memory range, reported as motherboard resource by SIRC
+       @note
+           If this controller is located at function 0 and it's mode is set to hidden it will not be visible in the PCI space.
+**/
+typedef enum {
+  SerialIoSpiDisabled,
+  SerialIoSpiPci,
+  SerialIoSpiHidden
+} SERIAL_IO_SPI_MODE;
+
+/**
+  Used to set Inactive/Idle polarity of Spi Chip Select
+**/
+typedef enum {
+  SerialIoSpiCsActiveLow  = 0,
+  SerialIoSpiCsActiveHigh = 1
+} SERIAL_IO_CS_POLARITY;
+
+/**
+  The SERIAL_IO_SPI_CONFIG provides the configurations to set the Serial IO SPI controller
+**/
+typedef struct {
+  UINT8 Mode;                                          ///< <b>SerialIoSpiPci </b> see SERIAL_IO_SPI_MODE
+  UINT8 DefaultCsOutput;                               ///< <b>0 = CS0</b> CS1, CS2, CS3. Default CS used by the SPI HC
+  UINT8 CsPolarity[PCH_MAX_SERIALIO_SPI_CHIP_SELECTS]; ///< Selects SPI ChipSelect signal polarity, 0 = low <b>1 = High</b>
+  UINT8 CsEnable[PCH_MAX_SERIALIO_SPI_CHIP_SELECTS];   ///< <b>0 = Enable</b> 1 = Disable. Based on this setting GPIO for given SPIx CSx will be configured in Native mode
+  UINT8 CsMode;                                        ///< <b>0 = HW Control</b> 1 = SW Control. Sets Chip Select Control mode Hardware or Software.
+  UINT8 CsState;                                       ///< <b>0 = CS is set to low</b> 1 = CS is set to high
+} SERIAL_IO_SPI_CONFIG;
+
+/**
+  Available working modes for SerialIo UART Host Controller
+
+       0: SerialIoUartDisabled;
+          - Device is placed in D3
+          - Gpio configuration is skipped
+          - PSF:
+          !important! If given device is Function 0 and other higher functions on given device
+                      are enabled, PSF disabling is skipped. PSF default will remain and device PCI CFG Space will still be visible.
+                      This is needed to allow PCI enumerator access functions above 0 in a multifunction device.
+    <b>1: SerialIoUartPci;</b>
+          - Designated for Serial IO UART OS driver usage
+          - Gpio pin configuration in native mode for each assigned pin
+          - Device will be enabled in PSF
+          - Only BAR0 will be enabled
+       2: SerialIoUartHidden;
+          - Designated for BIOS and/or DBG2 OS kernel debug
+          - Gpio pin configuration in native mode for each assigned pin
+          - Device disabled in the PSF
+          - Both BARs are enabled, BAR1 becomes devices Pci Config Space
+          - BAR0 assigned from the global PCH reserved memory range, reported as motherboard resource by SIRC
+       @note
+           If this controller is located at function 0 and it's mode is set to hidden it will not be visible in the PCI space.
+       3: SerialIoUartCom;
+          - Designated for 16550/PNP0501 compatible COM device
+          - Gpio pin configuration in native mode for each assigned pin
+          - Device disabled in the PSF
+          - Both BARs are enabled, BAR1 becomes devices Pci Config Space
+          - BAR0 assigned from the global PCH reserved memory range, reported as motherboard resource by SIRC
+       4: SerialIoUartSkipInit;
+          - Gpio configuration is skipped
+          - PSF configuration is skipped
+          - BAR assignemnt is skipped
+          - D-satate setting is skipped
+
+**/
+typedef enum {
+  SerialIoUartDisabled,
+  SerialIoUartPci,
+  SerialIoUartHidden,
+  SerialIoUartCom,
+  SerialIoUartSkipInit
+} SERIAL_IO_UART_MODE;
+
+/**
+  UART Settings
+**/
+typedef struct {
+  UINT32      BaudRate;    ///< <b> 115200 </b> Max 6000000  MdePkg.dec  PcdUartDefaultBaudRate
+  UINT8       Parity;      ///< <b> 1 - No Parity</b> see EFI_PARITY_TYPE MdePkg.dec PcdUartDefaultParity
+  UINT8       DataBits;    ///< <b>8</b> MdePkg.dec PcdUartDefaultDataBits
+  UINT8       StopBits;    ///< <b>1 - One Stop Bit</b> see EFI_STOP_BITS_TYPE  MdePkg.dec  PcdUartDefaultStopBits
+  UINT8       AutoFlow;    ///< <b>FALSE</b>  IntelFrameworkModulePkg.dsc PcdIsaBusSerialUseHalfHandshake
+} SERIAL_IO_UART_ATTRIBUTES;
+
+/**
+  UART signals pin muxing settings. If signal can be enable only on a single pin
+  then this parameter is ignored by RC. Refer to GPIO_*_MUXING_SERIALIO_UARTx_* in GpioPins*.h
+  for supported settings on a given platform
+**/
+typedef struct {
+  UINT32 Rx;  ///< RXD Pin mux configuration. Refer to GPIO_*_MUXING_SERIALIO_UARTx_RXD_*
+  UINT32 Tx;  ///< TXD Pin mux configuration. Refer to GPIO_*_MUXING_SERIALIO_UARTx_TXD_*
+  UINT32 Rts; ///< RTS Pin mux configuration. Refer to GPIO_*_MUXING_SERIALIO_UARTx_RTS_*
+  UINT32 Cts; ///< CTS Pin mux configuration. Refer to GPIO_*_MUXING_SERIALIO_UARTx_CTS_*
+} UART_PIN_MUX;
+
+/**
+  Serial IO UART Controller Configuration
+**/
+typedef struct {
+  SERIAL_IO_UART_ATTRIBUTES Attributes;  ///< see SERIAL_IO_UART_ATTRIBUTES
+  UART_PIN_MUX              PinMux;      ///< UART pin mux configuration
+  UINT8                     Mode;        ///< <b> SerialIoUartPci </b> see SERIAL_IO_UART_MODE
+  UINT8                     DBG2;        ///< <b> FALSE </b> If TRUE adds UART to DBG2 table and overrides UartPg to SerialIoUartPgDisabled
+  UINT8                     PowerGating; ///< <b> SerialIoUartPgAuto </b> Applies to Hidden/COM/SkipInit see SERIAL_IO_UART_PG
+  UINT8                     DmaEnable;   ///< <b> TRUE </b> Applies to SerialIoUartPci only. Informs OS driver to use DMA, if false it will run in PIO mode
+} SERIAL_IO_UART_CONFIG;
+
+typedef enum {
+  SerialIoUartPgDisabled,  ///< No _PS0/_PS3 support, device left in D0, after initialization
+/**
+  In mode: SerialIoUartCom;
+           _PS0/_PS3  that supports getting device out of reset
+  In mode: SerialIoUartPci
+           Keeps UART in D0 and assigns Fixed MMIO for SEC/PEI usage only
+**/
+  SerialIoUartPgEnabled,
+  SerialIoUartPgAuto       ///< _PS0 and _PS3, detection through ACPI if device was initialized prior to first PG. If it was used (DBG2) PG is disabled,
+} SERIAL_IO_UART_PG;
+
+/**
+  Available working modes for SerialIo I2C Host Controller
+
+       0: SerialIoI2cDisabled;
+          - Device is placed in D3
+          - Gpio configuration is skipped
+          - PSF:
+          !important! If given device is Function 0 and other higher functions on given device
+                      are enabled, PSF disabling is skipped. PSF default will remain and device PCI CFG Space will still be visible.
+                      This is needed to allow PCI enumerator access functions above 0 in a multifunction device.
+    <b>1: SerialIoI2cPci;</b>
+          - Gpio pin configuration in native mode for each assigned pin
+          - Device will be enabled in PSF
+          - Only BAR0 will be enabled
+       2: SerialIoI2cHidden;
+          - Gpio pin configuration in native mode for each assigned pin
+          - Device disabled in the PSF
+          - Both BARs are enabled, BAR1 becomes devices Pci Config Space
+          - BAR0 assigned from the global PCH reserved memory range, reported as motherboard resource by SIRC
+       @note
+           If this controller is located at function 0 and it's mode is set to hidden it will not be visible in the PCI space.
+**/
+typedef enum {
+  SerialIoI2cDisabled,
+  SerialIoI2cPci,
+  SerialIoI2cHidden
+} SERIAL_IO_I2C_MODE;
+
+/**
+  I2C signals pin muxing settings. If signal can be enable only on a single pin
+  then this parameter is ignored by RC. Refer to GPIO_*_MUXING_SERIALIO_I2Cx_* in GpioPins*.h
+  for supported settings on a given platform
+**/
+typedef struct {
+  UINT32   Sda;   ///< SDA Pin mux configuration. Refer to GPIO_*_MUXING_SERIALIO_I2Cx_SDA_*
+  UINT32   Scl;   ///< SCL Pin mux configuration. Refer to GPIO_*_MUXING_SERIALIO_I2Cx_SCL_*
+} I2C_PIN_MUX;
+
+/**
+  Serial IO I2C Controller Configuration
+**/
+typedef struct {
+  UINT8        Mode;        /// <b>SerialIoI2cPci <b> see SERIAL_IO_I2C_MODE
+  /**
+    I2C Pads Internal Termination.
+    For more information please see Platform Design Guide.
+    Supported values (check GPIO_ELECTRICAL_CONFIG for reference):
+    <b>GpioTermNone: No termination</b>,
+    GpioTermWpu1K: 1kOhm weak pull-up,
+    GpioTermWpu5K: 5kOhm weak pull-up,
+    GpioTermWpu20K: 20kOhm weak pull-up
+  **/
+  UINT8        PadTermination;
+  UINT8        Reserved[2];
+  I2C_PIN_MUX  PinMux;      ///< I2C pin mux configuration
+} SERIAL_IO_I2C_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _SERIAL_IO_DEVICES_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/SiConfigHob.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/SiConfigHob.h
new file mode 100644
index 0000000000..191bd815a1
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/SiConfigHob.h
@@ -0,0 +1,17 @@
+/** @file
+  Silicon Config HOB is used for gathering platform
+  related Intel silicon information and config setting.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SI_CONFIG_HOB_H_
+#define _SI_CONFIG_HOB_H_
+
+#include <SiPolicyStruct.h>
+
+extern EFI_GUID gSiConfigHobGuid;
+
+// Rename SI_CONFIG_HOB into SI_CONFIG_HOB_DATA for it does not follow HOB structure.
+typedef CONST SI_CONFIG SI_CONFIG_HOB_DATA;
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Include/SiPolicyStruct.h b/Silicon/Intel/TigerlakeSiliconPkg/Include/SiPolicyStruct.h
new file mode 100644
index 0000000000..7b646d8972
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Include/SiPolicyStruct.h
@@ -0,0 +1,64 @@
+/** @file
+  Intel reference code configuration policies.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SI_POLICY_STRUCT_H_
+#define _SI_POLICY_STRUCT_H_
+
+#include <ConfigBlock.h>
+#include <ConfigBlock/SiPreMemConfig.h>
+#include <ConfigBlock/SiConfig.h>
+
+/**
+  Silicon Policy revision number
+  Any change to this structure will result in an update in the revision number
+
+  This member specifies the revision of the Silicon Policy. This field is used to indicate change
+  to the policy structure.
+
+  <b>Revision 1</b>:
+   - Initial version.
+**/
+#define SI_POLICY_REVISION  1
+
+/**
+  Silicon pre-memory Policy revision number
+  Any change to this structure will result in an update in the revision number
+
+  <b>Revision 1</b>:
+   - Initial version.
+**/
+#define SI_PREMEM_POLICY_REVISION  1
+
+
+/**
+  SI Policy PPI in Pre-Mem\n
+  All SI config block change history will be listed here\n\n
+
+  - <b>Revision 1</b>:
+    - Initial version.\n
+**/
+struct _SI_PREMEM_POLICY_STRUCT {
+  CONFIG_BLOCK_TABLE_HEADER      TableHeader;   ///< Config Block Table Header
+/*
+  Individual Config Block Structures are added here in memory as part of AddConfigBlock()
+*/
+};
+
+/**
+  SI Policy PPI\n
+  All SI config block change history will be listed here\n\n
+
+  - <b>Revision 1</b>:
+    - Initial version.\n
+**/
+struct _SI_POLICY_STRUCT {
+  CONFIG_BLOCK_TABLE_HEADER      TableHeader;   ///< Config Block Table Header
+/*
+  Individual Config Block Structures are added here in memory as part of AddConfigBlock()
+*/
+};
+
+#endif
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 04/40] TigerlakeSiliconPkg/Cpu: Add Include headers
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
  2021-02-05  7:40 ` [Patch V3 02/40] TigerlakeSiliconPkg/Include: Add Library, PPI and Protocol include headers Heng Luo
  2021-02-05  7:40 ` [Patch V3 03/40] TigerlakeSiliconPkg/Include: Add Pins, Register and other " Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 05/40] TigerlakeSiliconPkg/Pch: Add include headers Heng Luo
                   ` (35 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds header files common to CPU modules.

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfig.h                |  83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfigLibPreMemConfig.h | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPidTestConfig.h         |  52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtBasicConfig.h  | 226 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtCustomConfig.h |  76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtPsysConfig.h   |  36 ++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtTestConfig.h   | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuSecurityPreMemConfig.h  |  63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuTestConfig.h            |  51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/CpuAccess.h                            |  12 ++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/CpuDataStruct.h                        |  21 +++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/CpuPolicyCommon.h                      |  23 +++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/Register/CommonMsr.h                   |  18 ++++++++++++++++++
 13 files changed, 959 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfig.h
new file mode 100644
index 0000000000..d837500a38
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfig.h
@@ -0,0 +1,83 @@
+/** @file
+  CPU Config Block.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _CPU_CONFIG_H_
+#define _CPU_CONFIG_H_
+
+#define CPU_CONFIG_REVISION 3
+
+extern EFI_GUID gCpuConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  CPU Configuration Structure.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Add SmbiosType4MaxSpeedOverride.
+  <b>Revision 3</b>:
+  - Add AvxDisable & Avx3Disable.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  UINT32                MicrocodePatchRegionSize;
+  EFI_PHYSICAL_ADDRESS  MicrocodePatchAddress;    ///< Pointer to microcode patch that is suitable for this processor.
+  /**
+    Enable or Disable Advanced Encryption Standard (AES) feature.
+    For some countries, this should be disabled for legal reasons.
+    -    0: Disable
+    - <b>1: Enable</b>
+  **/
+  UINT32 AesEnable           : 1;
+  /**
+    Enable or Disable Trusted Execution Technology (TXT) feature.
+    -    0: Disable
+    - <b>1: Enable</b>
+  **/
+  UINT32 TxtEnable           : 1;
+  UINT32 SkipMpInit          : 1;                 ///< For Fsp only, Silicon Initialization will skip MP Initialization (including BSP) if enabled. For non-FSP, this should always be 0.
+  /**
+    Enable or Disable or Auto for PPIN Support to view Protected Processor Inventory Number.
+    - <b>0: Disable</b>
+    -    1: Enable
+    -    2: Auto : Feature is based on End Of Manufacturing (EOM) flag. If EOM is set, it is disabled.
+  **/
+  UINT32 PpinSupport         : 2;
+  /**
+    Enable or Disable #AC machine check on split lock.
+    - <b>0: Disable</b>
+    -    1: Enable
+  **/
+  UINT32 AcSplitLock         : 1;
+  /**
+  Enable or Disable Avx.
+  -      1: Disable
+  -  <b> 0: Enable</b>
+  **/
+  UINT32 AvxDisable          : 1;
+  /**
+  Enable or Disable Avx3.
+  -      1: Disable
+  -  <b> 0: Enable</b>
+  **/
+  UINT32 Avx3Disable         : 1;
+  UINT32 RsvdBits            : 24;                ///< Reserved for future use
+  /**
+    Provide the option for platform to override the MaxSpeed field of Smbios Type 4.
+    Value 4000 means 4000MHz.
+    If this value is not zero, it dominates the field.
+    If this value is zero, CPU RC will update the field according to the max radio.
+    <b>default is 0.</b>
+  **/
+  UINT16 SmbiosType4MaxSpeedOverride;
+  UINT8  Reserved0[2];                            ///< Reserved for future use
+} CPU_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfigLibPreMemConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfigLibPreMemConfig.h
new file mode 100644
index 0000000000..bf3f436ddd
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuConfigLibPreMemConfig.h
@@ -0,0 +1,148 @@
+/** @file
+  CPU Security PreMemory Config Block.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _CPU_CONFIG_LIB_PREMEM_CONFIG_H_
+#define _CPU_CONFIG_LIB_PREMEM_CONFIG_H_
+
+#define CPU_CONFIG_LIB_PREMEM_CONFIG_REVISION 6
+
+extern EFI_GUID gCpuConfigLibPreMemConfigGuid;
+
+#define BOOT_FREQUENCY_MAX_BATTERY_PERF   0
+#define BOOT_FREQUENCY_MAX_NON_TURBO_PERF 1
+#define BOOT_FREQUENCY_TURBO_PERF         2
+
+#pragma pack (push,1)
+
+/**
+  CPU Config Library PreMemory Configuration Structure.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Expand the supported number of processor cores (ActiveCoreCount1).
+  <b>Revision  3</b>:
+  - Added PECI Sx and C10 Reset.
+  <b>Revision  4</b>:
+  - Added ActiveSmallCoreCount.
+  <b>Revision  5</b>:
+  - Added CrashLogGprs
+  <b>Revision  6</b>:
+  - Added ConfigTdpLevel
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER Header;            ///< Config Block Header
+  UINT32 HyperThreading             : 1; ///< Enable or Disable Hyper Threading; 0: Disable; <b>1: Enable</b>.
+  /**
+  Sets the boot frequency starting from reset vector.
+   - 0: Maximum battery performance.
+   - 1: Maximum non-turbo performance
+   -<b>2: Turbo performance</b>.
+  @note If Turbo is selected BIOS will start in max non-turbo mode and switch to Turbo mode.
+  **/
+  UINT32 BootFrequency              : 2;
+  /**
+    Number of processor cores to enable.
+    - <b> 0: All cores</b>
+    -     1: 1 core
+    -     2: 2 cores
+    -     3: 3 cores
+  **/
+  UINT32 ActiveCoreCount            : 3; ///< @deprecated due to core active number limitaion.
+  UINT32 JtagC10PowerGateDisable    : 1; ///< False: JTAG is power gated in C10 state. True: keeps the JTAG power up during C10 and deeper power states for debug purpose. <b>0: False<\b>; 1: True.
+  UINT32 BistOnReset                : 1; ///< <b>(Test)</b> Enable or Disable BIST on Reset; <b>0: Disable</b>; 1: Enable.
+  /**
+    Enable or Disable Virtual Machine Extensions (VMX) feature.
+    -    0: Disable
+    - <b>1: Enable</b>
+  **/
+  UINT32 VmxEnable                  : 1;
+  /**
+  Processor Early Power On Configuration FCLK setting.
+   - <b>0: 800 MHz (ULT/ULX)</b>.
+   - <b>1: 1 GHz (DT/Halo)</b>. Not supported on ULT/ULX.
+   - 2: 400 MHz.
+   - 3: Reserved.
+  **/
+  UINT32 FClkFrequency              : 2;
+  /**
+  Enable or Disable CrashLog feature
+    -    0: Disable
+    - <b>1: Enable</b>
+  **/
+  UINT32 CrashLogEnable              : 1;
+
+  /**
+  Enable or Disable Total Memory Encryption (TME) feature.
+    - <b>0: Disable</b>
+    -    1: Enable
+  **/
+  UINT32 TmeEnable                  : 1;
+
+  UINT32 DebugInterfaceEnable       : 2; ///< Enable or Disable processor debug features; 0: Disable; 1: Enable; <b>2: No Change</b>.
+  UINT32 DebugInterfaceLockEnable   : 1; ///< Lock or Unlock debug interface features; 0: Disable; <b>1: Enable</b>.
+
+  /**
+    Number of big cores in processor to enable. And support up to 16 cores.
+    - <b> 0: All cores</b>
+    -     1: 1 core
+    -     2: 2 cores
+    -     3: 3 cores
+  **/
+  UINT32 ActiveCoreCount1           : 4;
+
+  /**
+  Enables a mailbox command to resolve rare PECI related Sx issues.
+  @note This should only be used on systems that observe PECI Sx issues.
+  - <b>0: Disable</b>
+  -    1: Enable
+  **/
+  UINT32 PeciSxReset                : 1;
+
+  /**
+  Enables the mailbox command to resolve PECI reset issues during Pkg-C10 exit.
+  If Enabled, BIOS will send the CPU message to disable peci reset on C10 exit.
+  The default value is <b>1: Enable</b> for CML, and <b>0: Disable</b> for all other CPU's
+  - 0: Disable
+  - 1: Enable
+  **/
+  UINT32 PeciC10Reset               : 1;
+
+  /**
+    Number of small cores in processor to enable. And support the enabling of up to 63 cores.
+    - <b> 0: All cores</b>
+    -     1: 1 core
+    -     2: 2 cores
+    -     3: 3 cores
+  **/
+  UINT32 ActiveSmallCoreCount       : 6;
+
+  /**
+  Enable or Disable CrashLog GPRs dump
+    - <b>0: Disable</b>
+    -    1: Gprs Enabled, Smm Gprs Enabled
+         2: Gprs Enabled, Smm Gprs Disabled
+  **/
+  UINT32 CrashLogGprs               : 2;
+
+  UINT32 RsvdBits                   : 2;
+
+  /**
+    CpuRatio - Max non-turbo ratio (Flexible Ratio Boot) is set to CpuRatio. <b>0: Disabled</b> If disabled, doesn't override max-non turbo ratio.
+  **/
+  UINT8  CpuRatio;
+  /**
+    Configuration for boot TDP selection; <b>0: TDP Nominal</b>; 1: TDP Down; 2: TDP Up.
+  **/
+  UINT8  ConfigTdpLevel;
+  UINT8  Reserved[2];                    ///< Reserved for alignment
+  UINT32 ElixirSpringsPatchAddr;         ///< Address of Elixir Springs Patch(es)
+  UINT32 ElixirSpringsPatchSize;         ///< Elixir Springs Patch(es) Size.
+} CPU_CONFIG_LIB_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_CONFIG_LIB_PREMEM_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPidTestConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPidTestConfig.h
new file mode 100644
index 0000000000..4fcb92cb27
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPidTestConfig.h
@@ -0,0 +1,52 @@
+/** @file
+  CPU PID Config Block.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _CPU_PID_TEST_CONFIG_H_
+#define _CPU_PID_TEST_CONFIG_H_
+
+#define CPU_PID_TEST_CONFIG_REVISION 1
+
+extern EFI_GUID gCpuPidTestConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  PID Tuning Configuration Structure.
+  Domain is mapped to Kp = 0, Ki = 1, Kd = 2.
+
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  UINT16  Ratl[3];                                ///< RATL setting, in 1/256 units. Range is 0 - 65280
+  UINT16  VrTdcVr0[3];                            ///< VR Thermal Design Current for VR0. In 1/256 units. Range is 0 - 65280
+  UINT16  VrTdcVr1[3];                            ///< VR Thermal Design Current for VR1. In 1/256 units. Range is 0 - 65280
+  UINT16  VrTdcVr2[3];                            ///< VR Thermal Design Current for VR2. In 1/256 units. Range is 0 - 65280
+  UINT16  VrTdcVr3[3];                            ///< VR Thermal Design Current for VR3. In 1/256 units. Range is 0 - 65280
+  UINT16  PbmPsysPl1Msr[3];                       ///< Power Budget Management Psys PL1 MSR. In 1/256 units. Range is 0 - 65280
+  UINT16  PbmPsysPl1MmioPcs[3];                   ///< Power Budget Management Psys PL1 MMIO/PCS. In 1/256 units. Range is 0 - 65280
+  UINT16  PbmPsysPl2Msr[3];                       ///< Power Budget Management Psys PL2 MSR. In 1/256 units. Range is 0 - 65280
+  UINT16  PbmPsysPl2MmioPcs[3];                   ///< Power Budget Management Psys PL2 MMIO/PCS. In 1/256 units. Range is 0 - 65280
+  UINT16  PbmPkgPl1Msr[3];                        ///< Power Budget Management Package PL1 MSR. In 1/256 units. Range is 0 - 65280
+  UINT16  PbmPkgPl1MmioPcs[3];                    ///< Power Budget Management Package PL1 MMIO/PCS. In 1/256 units. Range is 0 - 65280
+  UINT16  PbmPkgPl2Msr[3];                        ///< Power Budget Management Package PL2 MSR. In 1/256 units. Range is 0 - 65280
+  UINT16  PbmPkgPl2MmioPcs[3];                    ///< Power Budget Management Package PL2 MMIO/PCS. In 1/256 units. Range is 0 - 65280
+  UINT16  DdrPl1Msr[3];                           ///< DDR PL1 MSR. In 1/256 units. Range is 0 - 65280
+  UINT16  DdrPl1MmioPcs[3];                       ///< DDR PL1 MMIO/PCS. In 1/256 units. Range is 0 - 65280
+  UINT16  DdrPl2Msr[3];                           ///< DDR PL2 MSR. In 1/256 units. Range is 0 - 65280
+  UINT16  DdrPl2MmioPcs[3];                       ///< DDR PL2 MMIO/PCS. In 1/256 units. Range is 0 - 65280
+  /**
+  Enable or Disable PID Tuning programming flow.
+  If disabled, all other policies in this config block are ignored.
+  **/
+  UINT8   PidTuning;
+  UINT8   Rsvd;                                   ///< Reserved for DWORD alignment.
+} CPU_PID_TEST_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_PID_TEST_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtBasicConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtBasicConfig.h
new file mode 100644
index 0000000000..0255d49bdf
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtBasicConfig.h
@@ -0,0 +1,226 @@
+/** @file
+  CPU Power Management Basic Config Block.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _CPU_POWER_MGMT_BASIC_CONFIG_H_
+#define _CPU_POWER_MGMT_BASIC_CONFIG_H_
+
+#define CPU_POWER_MGMT_BASIC_CONFIG_REVISION 5
+
+extern EFI_GUID gCpuPowerMgmtBasicConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  CPU Power Management Basic Configuration Structure.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Changed EnableItbm default to be disable
+  - Deprecated EnableItbmDriver due to Platform doesn't have ITBMT OS driver
+  <b>Revision 3</b>:
+  - Add ApplyConfigTdp for TDP initialization settings based on non-cTDP or cTDP
+  <b>Revision 4</b>:
+  - Add Hwp Lock support
+  <b>Revision 5</b>:
+  - Add VccInDemotionOverride and VccInDemotionMs
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  /**
+  Sets the boot frequency starting from reset vector.
+   - 0: Maximum battery performance.
+   - 1: Maximum non-turbo performance.
+   - <b>2: Turbo performance.</b>
+  @note If Turbo is selected BIOS will start in max non-turbo mode and switch to Turbo mode.
+  **/
+  UINT32 BootFrequency                  : 2;       //@deprecated
+  UINT32 SkipSetBootPState              : 1;      ///< Choose whether to skip SetBootPState function for all APs; <b>0: Do not skip</b>; 1: Skip.
+  /**
+  Enable or Disable Intel Speed Shift Technology.
+  Enabling allows for processor control of P-state transitions.
+  0: Disable; <b>1: Enable;</b> Bit 1 is ignored.
+  @note Currently this feature is recommended to be enabled only on win10
+  **/
+  UINT32 Hwp                            : 2;
+  /**
+  Hardware Duty Cycle Control configuration. 0: Disabled; <b>1: Enabled</b> 2-3:Reserved
+  HDC enables the processor to autonomously force components to enter into an idle state to lower effective frequency.
+  This allows for increased package level C6 residency.
+  @note Currently this feature is recommended to be enabled only on win10
+  **/
+  UINT32 HdcControl                     : 2;
+  UINT32 PowerLimit2                    : 1;      ///< Enable or Disable short duration Power Limit (PL2). 0: Disable; <b>1: Enable</b>
+  UINT32 TurboPowerLimitLock            : 1;      ///< MSR 0x610[63] and 0x618[63]: Locks all Turbo power limit settings to read-only; <b>0: Disable</b>; 1: Enable (Lock).
+  UINT32 PowerLimit3DutyCycle           : 8;      ///< Package PL3 Duty Cycle. Specifies the PL3 duty cycle percentage, Range 0-100. <b>Default: 0</b>.
+  UINT32 PowerLimit3Lock                : 1;      ///< Package PL3 MSR 615h lock; <b>0: Disable</b>; 1: Enable (Lock).
+  UINT32 PowerLimit4Lock                : 1;      ///< Package PL4 MSR 601h lock; <b>0: Disable</b>; 1: Enable (Lock).
+  /**
+  Tcc Offset Clamp for Runtime Average Temperature Limit (RATL) allows CPU to throttle below P1.
+  For Y SKU, the recommended default for this policy is <b>1: Enabled</b>, which indicates throttling below P1 is allowed.
+  For all other SKUs the recommended default are  <b>0: Disabled</b>.
+  **/
+  UINT32 TccOffsetClamp                 : 1;
+  UINT32 TccOffsetLock                  : 1;      ///< Tcc Offset Lock for Runtime Average Temperature Limit (RATL) to lock temperature target MSR 1A2h; 0: Disabled; <b>1: Enabled (Lock)</b>.
+  UINT32 TurboMode                      : 1;      ///< Enable or Disable Turbo Mode. Disable; <b>1: Enable</b>
+  UINT32 HwpInterruptControl            : 1;      ///< Set HW P-State Interrupts Enabled  for MISC_PWR_MGMT MSR 0x1AA[7]; <b>0: Disable</b>; 1: Enable.
+  UINT32 ApplyConfigTdp                 : 1;      ///< Switch TDP applied setting based on non-cTDP or TDP; 0: non-cTDP; <b>1: cTDP</b>.
+  UINT32 HwpLock                        : 1;      ///< HWP Lock in MISC PWR MGMT MSR 1AAh; <b>0: Disable</b>; 1: Enable (Lock).
+  UINT32 VccInDemotionOverride          : 1;      ///< Enable VccIn Demotion Override configuration. <b>0: Disable</b>; 1: Enable.
+  UINT32 RsvdBits                       : 6;      ///< Reserved for future use.
+
+  /**
+   1-Core Ratio Limit: LFM to Fused 1-Core Ratio Limit. For overclocking parts: LFM to Fused 1-Core Ratio Limit + OC Bins.
+   Note: OC Bins = 7 means fully unlocked, so range is LFM to 83.
+     - This 1-Core Ratio Limit Must be greater than or equal to 2-Core Ratio Limit, 3-Core Ratio Limit, 4-Core Ratio Limit.
+  **/
+  UINT8  OneCoreRatioLimit;
+  /**
+   2-Core Ratio Limit: LFM to Fused 2-Core Ratio Limit, For overclocking part: LFM to Fused 2-Core Ratio Limit + OC Bins.
+   Note: OC Bins = 7 means fully unlocked, so range is LFM to 83.
+     - This 2-Core Ratio Limit Must be Less than or equal to 1-Core Ratio Limit.
+  **/
+  UINT8  TwoCoreRatioLimit;
+  /**
+   3-Core Ratio Limit: LFM to Fused 3-Core Ratio Limit, For overclocking part: LFM to Fused 3-Core Ratio Limit + OC Bins.
+   Note: OC Bins = 7 means fully unlocked, so range is LFM to 83.
+     - This 3-Core Ratio Limit Must be Less than or equal to 1-Core Ratio Limit.
+  **/
+  UINT8  ThreeCoreRatioLimit;
+  /**
+   4-Core Ratio Limit: LFM to Fused 4-Core Ratio Limit, For overclocking part: LFM to Fused 4-Core Ratio Limit + OC Bins.
+   Note: OC Bins = 7 means fully unlocked, so range is LFM to 83.
+     - This 4-Core Ratio Limit Must be Less than or equal to 1-Core Ratio Limit.
+  **/
+  UINT8  FourCoreRatioLimit;
+  /**
+   5-Core Ratio Limit: LFM to Fused 5-Core Ratio Limit, For overclocking part: LFM to Fused 5-Core Ratio Limit + OC Bins.
+   Note: OC Bins = 7 means fully unlocked, so range is LFM to 83.
+     - This 5-Core Ratio Limit Must be Less than or equal to 1-Core Ratio Limit.
+  **/
+  UINT8  FiveCoreRatioLimit;
+  /**
+   6-Core Ratio Limit: LFM to Fused 6-Core Ratio Limit, For overclocking part: LFM to Fused 6-Core Ratio Limit + OC Bins.
+   Note: OC Bins = 7 means fully unlocked, so range is LFM to 83.
+     - This 6-Core Ratio Limit Must be Less than or equal to 1-Core Ratio Limit.
+  **/
+  UINT8  SixCoreRatioLimit;
+  /**
+   7-Core Ratio Limit: LFM to Fused 7-Core Ratio Limit, For overclocking part: LFM to Fused 7-Core Ratio Limit + OC Bins.
+   Note: OC Bins = 7 means fully unlocked, so range is LFM to 83.
+     - This 7-Core Ratio Limit Must be Less than or equal to 1-Core Ratio Limit.
+  **/
+  UINT8  SevenCoreRatioLimit;
+  /**
+   8-Core Ratio Limit: LFM to Fused 8-Core Ratio Limit, For overclocking part: LFM to Fused 8-Core Ratio Limit + OC Bins.
+   Note: OC Bins = 7 means fully unlocked, so range is LFM to 83.
+     - This 8-Core Ratio Limit Must be Less than or equal to 1-Core Ratio Limit.
+  **/
+  UINT8  EightCoreRatioLimit;
+  /**
+  TCC Activation Offset. Offset from factory set TCC activation temperature at which the Thermal Control Circuit must be activated.
+  TCC will be activated at (TCC Activation Temperature - TCC Activation Offset), in degrees Celcius.
+  For Y SKU, the recommended default for this policy is  <b>10</b>
+  For all other SKUs the recommended default are <b>0</b>, causing TCC to activate at TCC Activation temperature.
+  @note The policy is recommended for validation purpose only.
+  **/
+  UINT8  TccActivationOffset;
+  /**
+  Intel Turbo Boost Max Technology 3.0
+  Enabling it on processors with OS support will allow OS to exploit the diversity in max turbo frequency of the cores.
+  <b>0: Disable</b>; 1: Enable;
+  **/
+  UINT8  EnableItbm                     : 1;
+  /**
+  @deprecated: Platform doesn't have Intel Turbo Boost Max Technology 3.0 Driver
+  Enabling it will load the driver upon ACPI device with HID = INT3510.
+  <b> 0: Disable;</b> 1: Enable;
+  **/
+  UINT8  EnableItbmDriver               : 1;
+  /**
+  Per Core P State OS control mode
+  Disabling will set PCU_MISC_CONFIG (Command 0x06) Bit 31 = 1. When set, the highest core request is used for all other core requests.
+  0: Disable;<b> 1: Enable;</b>
+  **/
+  UINT8  EnablePerCorePState            : 1;
+  /**
+  HwP Autonomous Per Core P State
+  Disabling will set Bit 30 = 1, command 0x11. When set, autonomous will request the same value
+  for all cores all the time.
+  0: Disable;<b> 1: Enable;</b>
+  **/
+  UINT8  EnableHwpAutoPerCorePstate     : 1;
+  /**
+  HwP Autonomous EPP grouping.
+  Disabling will set Bit 29 = 1, command 0x11. When set, autonomous will not necesarrily request the same value
+  for all cores with same EPP.
+  Enabling will clean Bit 29 = 0, command 0x11. Autonomous will request same values for all cores with same EPP.
+  0: Disable;<b> 1: Enable;</b>
+  **/
+  UINT8  EnableHwpAutoEppGrouping       : 1;
+  /**
+  EPB override over PECI
+  Enable by sending pcode command 0x2b , subcommand 0x3 to 1.
+  This will allow OOB EPB PECI override control.
+  <b>0: Disable;</b> 1: Enable;
+  **/
+  UINT8  EnableEpbPeciOverride          : 1;
+  /**
+  Support for Fast MSR for IA32_HWP_REQUEST.
+  On systems with HwP enabled, if this feature is available as indicated by MSR 0x65F[0] = 1,
+  set MSR 0x657[0] = 1.
+  0: Disable; <b> 1: Enable;</b>
+  **/
+  UINT8  EnableFastMsrHwpReq            : 1;
+  UINT8  ReservedBits1                  : 1;      ///< Reserved for future use.
+  UINT8  MinRingRatioLimit;                       ///< Minimum Ring Ratio Limit. Range from 0 to Max Turbo Ratio. 0 = AUTO/HW Default
+  UINT8  MaxRingRatioLimit;                       ///< Maximum Ring Ratio Limit. Range from 0 to Max Turbo Ratio. 0 = AUTO/HW Default
+  /**
+  Package Long duration turbo mode power limit (PL1).
+  Default is the TDP power limit of processor. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit.
+  **/
+  UINT16 PowerLimit1;
+  /**
+  Package Short duration turbo mode power limit (PL2). Allows for short excursions above TDP power limit.
+  Default = 1.25 * TDP Power Limit. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit.
+  **/
+  UINT16 PowerLimit2Power;
+  /**
+  Package PL3 power limit. PL3 is the CPU Peak Power Occurences Limit.
+  <b>Default: 0</b>. Range 0-65535. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit.
+  **/
+  UINT16 PowerLimit3;
+  /**
+  Package PL4 power limit. PL4 is a Preemptive CPU Package Peak Power Limit, it will never be exceeded.
+  Power is premptively lowered before limit is reached. <b>Default: 0</b>. Range 0-65535.
+  Units are based on POWER_MGMT_CONFIG.CustomPowerUnit.
+  **/
+  UINT16 PowerLimit4;
+  /**
+  Package Long duration turbo mode power limit (PL1) time window in seconds.
+  Used in calculating the average power over time.
+  Mobile: <b> 28s</b>
+  Desktop: <b> 8s</b>
+  Range: 0 - 128s
+  **/
+  UINT32 PowerLimit1Time;
+  UINT32 PowerLimit3Time;                         ///< Package PL3 time window. Range from 3ms to 64ms.
+  /**
+  Tcc Offset Time Window can range from 5ms to 448000ms for Runtime Average Temperature Limit (RATL).
+  For Y SKU, the recommended default for this policy is <b>5000: 5 seconds</b>, For all other SKUs the recommended default are <b>0: Disabled</b>
+  **/
+  UINT32 TccOffsetTimeWindowForRatl;
+  /**
+  Customize the VccIn Demotion in ms accordingly. Values used by OEM expected to be in lower end of 1-30 ms range.
+  Value 1 means 1ms, value 2 means 2ms, and so on. Value 0 will disable VccIn Demotion knob.
+  <b> It's 30ms by silicon default</b>.
+  **/
+  UINT32 VccInDemotionMs;
+} CPU_POWER_MGMT_BASIC_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_POWER_MGMT_BASIC_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtCustomConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtCustomConfig.h
new file mode 100644
index 0000000000..e1a5bcc684
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtCustomConfig.h
@@ -0,0 +1,76 @@
+/** @file
+  CPU Power Managment Custom Config Block.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _CPU_POWER_MGMT_CUSTOM_CONFIG_H_
+#define _CPU_POWER_MGMT_CUSTOM_CONFIG_H_
+
+#define CPU_POWER_MGMT_CUSTOM_CONFIG_REVISION 1
+
+extern EFI_GUID gCpuPowerMgmtCustomConfigGuid;
+
+#pragma pack (push,1)
+
+///
+/// Defines the maximum number of custom ratio states supported.
+///
+#define MAX_CUSTOM_RATIO_TABLE_ENTRIES    40
+#define MAX_16_CUSTOM_RATIO_TABLE_ENTRIES 16
+
+///
+/// Defines the maximum number of custom ConfigTdp entries supported.
+/// @warning: Changing this define would cause DWORD alignment issues in policy structures.
+///
+#define MAX_CUSTOM_CTDP_ENTRIES 3
+
+///
+/// This structure is used to describe the custom processor ratio table desired by the platform.
+///
+typedef struct {
+  UINT8  MaxRatio;                                           ///< The maximum ratio of the custom ratio table.
+  UINT8  NumberOfEntries;                                    ///< The number of custom ratio state entries, ranges from 2 to 40 for a valid custom ratio table.
+  UINT8  Rsvd0[2];                                           ///< Reserved for DWORD alignment.
+  UINT32 Cpuid;                                              ///< The CPU ID for which this custom ratio table applies.
+  UINT8  StateRatio[MAX_CUSTOM_RATIO_TABLE_ENTRIES];         ///< The processor ratios in the custom ratio table.
+  ///
+  /// If there are more than 16 total entries in the StateRatio table, then use these 16 entries to fill max 16 table.
+  /// @note If NumberOfEntries is 16 or less, or the first entry of this table is 0, then this table is ignored,
+  /// and up to the top 16 values from the StateRatio table is used instead.
+  ///
+  UINT8  StateRatioMax16[MAX_16_CUSTOM_RATIO_TABLE_ENTRIES];
+#if ((MAX_CUSTOM_RATIO_TABLE_ENTRIES + MAX_16_CUSTOM_RATIO_TABLE_ENTRIES) % 4)
+  UINT8  Rsvd1[4 - ((MAX_CUSTOM_RATIO_TABLE_ENTRIES + MAX_16_CUSTOM_RATIO_TABLE_ENTRIES) % 4)];  ///< If needed, add padding for dword alignment.
+#endif
+} PPM_CUSTOM_RATIO_TABLE;
+
+///
+/// PPM Custom ConfigTdp Settings
+///
+typedef struct _PPM_CUSTOM_CTDP_TABLE {
+  UINT32 CustomPowerLimit1Time      :  8;            ///< Short term Power Limit time window value for custom cTDP level.
+  UINT32 CustomTurboActivationRatio :  8;            ///< Turbo Activation Ratio for custom cTDP level.
+  UINT32 RsvdBits                   : 16;            ///< Bits reserved for DWORD alignment.
+  UINT16 CustomPowerLimit1;                          ///< Short term Power Limit value for custom cTDP level. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit.
+  UINT16 CustomPowerLimit2;                          ///< Long term Power Limit value for custom cTDP level. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit.
+} PPM_CUSTOM_CTDP_TABLE;
+
+/**
+  CPU Power Management Custom Configuration Structure.
+
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER    Header;                                                ///< Config Block Header
+  PPM_CUSTOM_RATIO_TABLE CustomRatioTable;                                      ///< Custom Processor Ratio Table Instance
+  PPM_CUSTOM_CTDP_TABLE  CustomConfigTdpTable[MAX_CUSTOM_CTDP_ENTRIES];         ///< Custom ConfigTdp Settings Instance
+  UINT32                 ConfigTdpLock  : 1;                                    ///< Lock the ConfigTdp mode settings from runtime changes; <b>0: Disable</b>; 1: Enable.
+  UINT32                 ConfigTdpBios  : 1;                                    ///< Configure whether to load Configurable TDP SSDT; <b>0: Disable</b>; 1: Enable.
+  UINT32                 RsvdBits       : 30;                                   ///< Reserved for future use
+} CPU_POWER_MGMT_CUSTOM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_POWER_MGMT_CUSTOM_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtPsysConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtPsysConfig.h
new file mode 100644
index 0000000000..f1ceb8f43b
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtPsysConfig.h
@@ -0,0 +1,36 @@
+/** @file
+  CPU Power Management Psys(Platform) Config Block.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _CPU_POWER_MGMT_PSYS_CONFIG_H_
+#define _CPU_POWER_MGMT_PSYS_CONFIG_H_
+
+#define CPU_POWER_MGMT_PSYS_CONFIG_REVISION 1
+
+extern EFI_GUID gCpuPowerMgmtPsysConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  CPU Power Management Psys(Platform) Configuration Structure.
+
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  UINT32 PsysPowerLimit1       : 1;               ///< MSR 0x65C[15]: PL1 Enable activates the PL1 value to limit average platform power
+  UINT32 PsysPowerLimit1Time   : 8;               ///< MSR 0x65C[23:17]: PL1 timewindow in seconds.
+  UINT32 PsysPowerLimit2       : 1;               ///< MSR 0x65C[47]: PL2 Enable activates the PL2 value to limit average platform power
+  UINT32 RsvdBits              : 22;              ///< Reserved for future use.
+  UINT16 PsysPowerLimit1Power;                    ///< MSR 0x65C[14:0]: Platform PL1 power. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit.
+  UINT16 PsysPowerLimit2Power;                    ///< MSR 0x65C[46:32]]: Platform PL2 power. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit.
+  UINT16 PsysPmax;                                ///< PCODE MMIO Mailbox: Platform Power Pmax. <b>0 - Auto</b> Specified in 1/8 Watt increments. 0-1024 Watts. Value of 800 = 100W.
+  UINT8  Rsvd[2];                                 ///< Reserved for future use and config block alignment
+} CPU_POWER_MGMT_PSYS_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_POWER_MGMT_PSYS_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtTestConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtTestConfig.h
new file mode 100644
index 0000000000..bd641f27c5
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuPowerMgmtTestConfig.h
@@ -0,0 +1,150 @@
+/** @file
+  CPU Power Management Test Config Block.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _CPU_POWER_MGMT_TEST_CONFIG_H_
+#define _CPU_POWER_MGMT_TEST_CONFIG_H_
+
+#define CPU_POWER_MGMT_TEST_CONFIG_REVISION 4
+
+extern EFI_GUID gCpuPowerMgmtTestConfigGuid;
+
+#pragma pack (push,1)
+
+///
+/// PPM Package C State Limit
+///
+typedef enum {
+  PkgC0C1                 = 0,
+  PkgC2,
+  PkgC3,
+  PkgC6,
+  PkgC7,
+  PkgC7s,
+  PkgC8,
+  PkgC9,
+  PkgC10,
+  PkgCMax,
+  PkgCpuDefault = 254,
+  PkgAuto = 255
+} MAX_PKG_C_STATE;
+
+///
+/// PPM Package C State Time Limit
+///
+typedef enum {
+  TimeUnit1ns             = 0,
+  TimeUnit32ns,
+  TimeUnit1024ns,
+  TimeUnit32768ns,
+  TimeUnit1048576ns,
+  TimeUnit33554432ns,
+  TimeUnitMax
+} C_STATE_TIME_UNIT;
+
+///
+/// Custom Power Units. User can choose to enter in watts or 125 milliwatt increments.
+///
+typedef enum {
+  PowerUnitWatts = 0,     ///< in Watts.
+  PowerUnit125MilliWatts, ///< in 125 milliwatt increments. Example: 90 power units times 125 mW equals 11.250 W.
+  PowerUnitMax
+} CUSTOM_POWER_UNIT;
+
+///
+/// PPM Interrupt Redirection Mode Selection
+///
+typedef enum {
+  PpmIrmFixedPriority     = 0,
+  PpmIrmRoundRobin,
+  PpmIrmHashVector,
+  PpmIrmReserved1,
+  PpmIrmReserved2,
+  PpmIrmReserved3,
+  PpmIrmReserved4,
+  PpmIrmNoChange
+} PPM_IRM_SETTING;
+
+/**
+  CPU Power Management Test Configuration Structure.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Add  CstateLatencyControl0TimeUnit for WHL only
+  - Add  CstateLatencyControl0Irtl for WHL only
+  <b>Revision 3</b>:
+  - Change C State LatencyContol to Auto as default.
+  <b>Revision 4</b>:
+  - Deprecate ConfigTdpLevel. Move to premem.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                    ///< Offset 0-27  Config Block Header
+  UINT32 Eist                          : 1;        ///< Offset 28-31 Enable or Disable Intel SpeedStep Technology. 0: Disable; <b>1: Enable</b>
+  UINT32 EnergyEfficientPState         : 1;        ///<              Enable or Disable Energy Efficient P-state will be applied in Turbo mode. Disable; <b>1: Enable</b>
+  UINT32 EnergyEfficientTurbo          : 1;        ///<              Enable or Disable Energy Efficient Turbo, will be applied in Turbo mode. Disable; <b>1: Enable</b>
+  UINT32 TStates                       : 1;        ///<              Enable or Disable T states; <b>0: Disable</b>; 1: Enable.
+  UINT32 BiProcHot                     : 1;        ///<              Enable or Disable Bi-Directional PROCHOT#; 0: Disable; <b>1: Enable</b>.
+  UINT32 DisableProcHotOut             : 1;        ///<              Enable or Disable PROCHOT# signal being driven externally; 0: Disable; <b>1: Enable</b>.
+  UINT32 ProcHotResponse               : 1;        ///<              Enable or Disable PROCHOT# Response; <b>0: Disable</b>; 1: Enable.
+  UINT32 DisableVrThermalAlert         : 1;        ///<              Enable or Disable VR Thermal Alert; <b>0: Disable</b>; 1: Enable.
+  UINT32 EnableAllThermalFunctions     : 1;        ///<              Enable or Disable Thermal Reporting through ACPI tables; 0: Disable; <b>1: Enable</b>.
+  UINT32 ThermalMonitor                : 1;        ///<              Enable or Disable Thermal Monitor; 0: Disable; <b>1: Enable</b>.
+  UINT32 Cx                            : 1;        ///<              Enable or Disable CPU power states (C-states). 0: Disable; <b>1: Enable</b>
+  UINT32 PmgCstCfgCtrlLock             : 1;        ///<              If enabled, sets MSR 0xE2[15]; 0: Disable; <b>1: Enable</b>.
+  UINT32 C1e                           : 1;        ///<              Enable or Disable Enhanced C-states. 0: Disable; <b>1: Enable</b>
+  UINT32 C1AutoDemotion                : 1;        ///<              Enable or Disable C6/C7 auto demotion to C1. 0: Disabled; <b>1: C1 Auto demotion</b>
+  UINT32 C1UnDemotion                  : 1;        ///<              Enable or Disable C1UnDemotion. 0: Disabled; <b>1: C1 Auto undemotion</b>
+  UINT32 C3AutoDemotion                : 1;        ///<              [CoffeeLake Only] Enable or Disable C6/C7 auto demotion to C3  0: Disabled; <b>1: C3 Auto demotion</b>
+  UINT32 C3UnDemotion                  : 1;        ///<              [CoffeeLake Only] Enable or Disable C3UnDemotion. 0: Disabled; <b>1: C3 Auto undemotion</b>
+  UINT32 PkgCStateDemotion             : 1;        ///<              Enable or Disable Package Cstate Demotion. Disable; <b>1: Enable</b> [WhiskeyLake] <b>Disable</b>; 1: Enable
+  UINT32 PkgCStateUnDemotion           : 1;        ///<              Enable or Disable Package Cstate UnDemotion. Disable; <b>1: Enable</b> [WhiskeyLake] <b>Disable</b>; 1: Enable
+  UINT32 CStatePreWake                 : 1;        ///<              Enable or Disable CState-Pre wake. Disable; <b>1: Enable</b>
+  UINT32 TimedMwait                    : 1;        ///<              Enable or Disable TimedMwait Support. <b>Disable</b>; 1: Enable
+  UINT32 CstCfgCtrIoMwaitRedirection   : 1;        ///<              Enable or Disable IO to MWAIT redirection; <b>0: Disable</b>; 1: Enable.
+  UINT32 ProcHotLock                   : 1;        ///<              If enabled, sets MSR 0x1FC[23]; <b>0: Disable</b>; 1: Enable.
+  UINT32 RaceToHalt                    : 1;        ///<              Enable or Disable Race To Halt feature; 0: Disable; <b>1: Enable </b>. RTH will dynamically increase CPU frequency in order to enter pkg C-State faster to reduce overall power. (RTH is controlled through MSR 1FC bit 20)
+  UINT32 ConfigTdpLevel                : 8;        ///<              @deprecated. Move to premem phase.
+  UINT16 CstateLatencyControl1Irtl;                ///< Offset 32-33 Interrupt Response Time Limit of LatencyContol1 MSR 0x60B[9:0].<b>0 is Auto</b>.
+  UINT16 CstateLatencyControl2Irtl;                ///< Offset 34-35 Interrupt Response Time Limit of LatencyContol2 MSR 0x60C[9:0].<b>0 is Auto</b>.
+  UINT16 CstateLatencyControl3Irtl;                ///< Offset 36-37 Interrupt Response Time Limit of LatencyContol3 MSR 0x633[9:0].<b>0 is Auto</b>.
+  UINT16 CstateLatencyControl4Irtl;                ///< Offset 38-39 Interrupt Response Time Limit of LatencyContol4 MSR 0x634[9:0].<b>0 is Auto</b>.
+  UINT16 CstateLatencyControl5Irtl;                ///< Offset 40-41 Interrupt Response Time Limit of LatencyContol5 MSR 0x635[9:0].<b>0 is Auto</b>.
+  // Due to the removal of CstateLatencyControl0Irtl, PkgCStateLimit is not aligned to 32-bit address.
+  UINT8  Rsvd1[2];                                 ///< Offset 42-43 Reserved for config block alignment.
+  MAX_PKG_C_STATE   PkgCStateLimit;                ///< Offset 44    This field is used to set the Max Pkg Cstate. Default set to Auto which limits the Max Pkg Cstate to deep C-state.
+  /**
+     @todo: The following enums have to be replaced with policies.
+  **/
+  C_STATE_TIME_UNIT Reserved;                      ///< Offset 45    Reserved for config block alignment.
+  C_STATE_TIME_UNIT CstateLatencyControl1TimeUnit; ///< Offset 46    TimeUnit for Latency Control1 MSR 0x60B[12:10]; <b>2: 1024ns</b>.
+  C_STATE_TIME_UNIT CstateLatencyControl2TimeUnit; ///< Offset 47    TimeUnit for Latency Control2 MSR 0x60C[12:10]; <b>2: 1024ns</b>.
+  C_STATE_TIME_UNIT CstateLatencyControl3TimeUnit; ///< Offset 48    TimeUnit for Latency Control3 MSR 0x633[12:10]; <b>2: 1024ns</b>.
+  C_STATE_TIME_UNIT CstateLatencyControl4TimeUnit; ///< Offset 49    TimeUnit for Latency Control4 MSR 0x634[12:10]; <b>2: 1024ns</b>.
+  C_STATE_TIME_UNIT CstateLatencyControl5TimeUnit; ///< Offset 50    TimeUnit for Latency Control5 MSR 0x635[12:10]; <b>2: 1024ns</b>.
+  /**
+  Offset 51  Default power unit in watts or in 125 milliwatt increments.
+  - 0: PowerUnitWatts.
+  - <b>1: PowerUnit125MilliWatts</b>.
+  **/
+  CUSTOM_POWER_UNIT CustomPowerUnit;
+  /**
+  Offset 52  Interrupt Redirection Mode Select.
+   - 0: Fixed priority.             //Default under CNL.
+   - 1: Round robin.
+   - 2: Hash vector.
+   - 4: PAIR with fixed priority.   //Default under KBL, not available under CNL.
+   - 5: PAIR with round robin.      //Not available under CNL.
+   - 6: PAIR with hash vector.      //Not available under CNL.
+   - 7: No change.
+  **/
+  PPM_IRM_SETTING      PpmIrmSetting;
+  // Move the padding to previous offset to align the structure at 32-bit address.
+  UINT8  Rsvd[4];                                 ///< Offset 53-56 Reserved for future use and config block alignment
+} CPU_POWER_MGMT_TEST_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_POWER_MGMT_TEST_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuSecurityPreMemConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuSecurityPreMemConfig.h
new file mode 100644
index 0000000000..24614fe497
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuSecurityPreMemConfig.h
@@ -0,0 +1,63 @@
+/** @file
+  CPU Security PreMemory Config Block.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _CPU_SECURITY_PREMEM_CONFIG_H_
+#define _CPU_SECURITY_PREMEM_CONFIG_H_
+
+#define CPU_SECURITY_PREMEM_CONFIG_REVISION 1
+
+extern EFI_GUID gCpuSecurityPreMemConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  CPU Security PreMemory Configuration Structure.
+
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER Header;                      ///< Config Block Header
+  UINT32              PrmrrSize;                   ///< PRMRR Size.<b>Software Control: 0x0</b>  32MB: 0x2000000, 64MB: 0x4000000, 128 MB: 0x8000000, 256 MB: 0x10000000, 512 MB: 0x20000000
+  UINT16              BiosSize;                    ///< Flash information for BIOS Guard: BIOS Size in KB.
+  UINT8               Reserved[2];                 ///< Reserved for future use
+/**
+   Enable or Disable BIOS Guard; 0: Disable; <b>1: Enable</b>.
+    - This is an optional feature and can be opted out.
+    - If this policy is set to Disabled, the policies in the BIOS_GUARD_CONFIG will be ignored.
+    - If PeiBiosGuardLibNull is used, this policy will have no effect.
+**/
+  UINT32              BiosGuard               :  1;
+  UINT32              BiosGuardToolsInterface :  1; ///< BIOS Guard Tools Interface; <b>0: Disable</b>, 1:Enable
+/**
+   Enable or Disable Software Guard Extensions; <b>0: Disable</b>; 1: Enable.
+    - This is an optional feature and can be opted out.
+    - If this policy is set to Disabled, the policies in the CPU_SGX_CONFIG will be ignored.
+    - If BaseSoftwareGuardLibNull is used, this policy will have no effect.
+**/
+  UINT32              EnableSgx               :  1;
+/**
+   Enable or Disable Trusted Execution Technology; <b>0: Disable</b>; 1: Enable.
+    - This is an optional feature and can be opted out.
+    - If this policy is set to Disabled, the policies in the CPU_TXT_PREMEM_CONFIG will be ignored.
+    - If PeiTxtLibNull is used, this policy will have no effect.
+**/
+  UINT32              Txt                     :  1;
+  UINT32              SkipStopPbet            :  1; ///< <b>(Test)</b> Skip Stop PBET Timer; <b>0: Disable</b>; 1: Enable.
+  ///
+  /// <b>(Test)</b> This policy indicates whether or not BIOS should allocate PRMRR memory for C6DRAM power gating feature.
+  ///  - 0: Don't allocate any PRMRR memory for C6DRAM power gating feature.
+  ///  - <b>1: Allocate PRMRR memory for C6DRAM power gating feature</b>.
+  ///
+  UINT32              EnableC6Dram            :  1;
+  UINT32              ResetAux                :  1; ///< <b>(Test)</b> Reset Auxiliary content, <b>0: Disabled</b>, 1: Enabled
+  UINT32              TxtAcheckRequest        :  1; ///< <b>(Test)</b> AcheckRequest <b>0: Disabled</b>, 1: Enabled. When Enabled, it will call Acheck regardless of crashcode value
+  UINT32              RsvdBits                : 24; ///< Reserved for future use
+} CPU_SECURITY_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_SECURITY_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuTestConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuTestConfig.h
new file mode 100644
index 0000000000..ee946290e0
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/ConfigBlock/CpuTestConfig.h
@@ -0,0 +1,51 @@
+/** @file
+  CPU Test Config Block.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _CPU_TEST_CONFIG_H_
+#define _CPU_TEST_CONFIG_H_
+
+#define CPU_TEST_CONFIG_REVISION 2
+
+extern EFI_GUID gCpuTestConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  CPU Test Configuration Structure.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Removed Voltage Optimization feature.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  UINT32                MlcStreamerPrefetcher           : 1;     ///< Enable or Disable MLC Streamer Prefetcher; 0: Disable; <b>1: Enable</b>.
+  UINT32                MlcSpatialPrefetcher            : 1;     ///< Enable or Disable MLC Spatial Prefetcher; 0: Disable; <b>1: Enable</b>.
+  UINT32                MonitorMwaitEnable              : 1;     ///< Enable or Disable Monitor /MWAIT instructions; 0: Disable; <b>1: Enable</b>.
+  UINT32                MachineCheckEnable              : 1;     ///< Enable or Disable initialization of machine check registers; 0: Disable; <b>1: Enable</b>.
+  UINT32                ProcessorTraceOutputScheme      : 1;     ///< Control on Processor Trace output scheme; <b>0: Single Range Output</b>; 1: ToPA Output.
+  UINT32                ProcessorTraceEnable            : 1;     ///< Enable or Disable Processor Trace feature; <b>0: Disable</b>; 1: Enable.
+  UINT32                ThreeStrikeCounterDisable       : 1;     ///< Disable Three strike counter; <b>0: FALSE</b>; 1: TRUE.
+  UINT32                RsvdBits                        : 25;     ///< Reserved for future use
+  /**
+     Base address of memory region allocated for Processor Trace.
+     Processor Trace requires 2^N alignment and size in bytes per thread, from 4KB to 128MB.
+     - <b>NULL: Disable</b>
+  **/
+  EFI_PHYSICAL_ADDRESS  ProcessorTraceMemBase;
+  /**
+     Length in bytes of memory region allocated for Processor Trace.
+     Processor Trace requires 2^N alignment and size in bytes per thread, from 4KB to 128MB.
+     - <b>0: Disable</b>
+  **/
+  UINT32                ProcessorTraceMemLength;
+  UINT8                 Reserved0[4];
+} CPU_TEST_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _CPU_TEST_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/CpuAccess.h b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/CpuAccess.h
new file mode 100644
index 0000000000..5d5e4df071
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/CpuAccess.h
@@ -0,0 +1,12 @@
+/** @file
+  Macros to simplify and abstract the interface to CPU configuration.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _CPUACCESS_H_
+#define _CPUACCESS_H_
+
+#include "CpuDataStruct.h"
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/CpuDataStruct.h b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/CpuDataStruct.h
new file mode 100644
index 0000000000..ba9a840e54
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/CpuDataStruct.h
@@ -0,0 +1,21 @@
+/** @file
+  This file declares various data structures used in CPU reference code.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_DATA_STRUCT_H
+#define _CPU_DATA_STRUCT_H
+
+///
+/// Structure to hold the return value of AsmCpuid instruction
+///
+typedef struct {
+  UINT32 RegEax; ///< Value of EAX.
+  UINT32 RegEbx; ///< Value of EBX.
+  UINT32 RegEcx; ///< Value of ECX.
+  UINT32 RegEdx; ///< Value of EDX.
+} EFI_CPUID_REGISTER;
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/CpuPolicyCommon.h b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/CpuPolicyCommon.h
new file mode 100644
index 0000000000..1178f68d0c
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/CpuPolicyCommon.h
@@ -0,0 +1,23 @@
+/** @file
+  CPU Policy Structure definition which will contain several config blocks during runtime.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _CPU_POLICY_COMMON_H_
+#define _CPU_POLICY_COMMON_H_
+
+#include <ConfigBlock.h>
+#include <ConfigBlock/CpuConfig.h>
+#include <ConfigBlock/CpuPidTestConfig.h>
+#include <ConfigBlock/CpuPowerMgmtBasicConfig.h>
+#include <ConfigBlock/CpuPowerMgmtCustomConfig.h>
+#include <ConfigBlock/CpuPowerMgmtPsysConfig.h>
+#include <ConfigBlock/CpuPowerMgmtTestConfig.h>
+#include <ConfigBlock/VoltageRegulator/CpuPowerMgmtVrConfig.h>
+#include <ConfigBlock/CpuTestConfig.h>
+#include <ConfigBlock/CpuSecurityPreMemConfig.h>
+#include <ConfigBlock/CpuConfigLibPreMemConfig.h>
+#include <OverclockingConfig.h>
+
+#endif // _CPU_POLICY_COMMON_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/Register/CommonMsr.h b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/Register/CommonMsr.h
new file mode 100644
index 0000000000..a2cd1db1d6
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Cpu/Include/Register/CommonMsr.h
@@ -0,0 +1,18 @@
+
+/** @file
+  CommonMsr.h
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _COMMONMSR_h
+#define _COMMONMSR_h
+#include <Base.h>
+
+/**
+  Special Chipset Usage MSR
+**/
+#define MSR_SPCL_CHIPSET_USAGE 0x000001FE
+
+#endif /* _COMMONMSR_h */
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 05/40] TigerlakeSiliconPkg/Pch: Add include headers
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (2 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 04/40] TigerlakeSiliconPkg/Cpu: Add Include headers Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 06/40] TigerlakeSiliconPkg/Pch: Add IncludePrivate headers Heng Luo
                   ` (34 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following header files:
  * Pch/Include

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/FlashProtectionConfig.h   |  55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/HsioConfig.h              |  57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/HsioPcieConfig.h          |  58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/HsioSataConfig.h          |  64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/LockDownConfig.h          |  61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/LpcConfig.h               |  38 ++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/PchGeneralConfig.h        |  72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Library/PchCycleDecodingLib.h         | 258 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Library/PchInfoLib.h                  | 590 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Library/PchPciBdfLib.h                | 552 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/PchInfoHob.h                          |  70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/PchLimits.h                           |  67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/PchPolicyCommon.h                     |  55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/PchPreMemPolicyCommon.h               |  56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/PchResetPlatformSpecific.h            |  21 +++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/IoTrapExDispatch.h           | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchAcpiSmiDispatch.h         | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchEspiSmiDispatch.h         | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchPcieSmiDispatch.h         | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchPolicy.h                  |  40 ++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchSmiDispatch.h             | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchSmmIoTrapControl.h        |  65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchSmmPeriodicTimerControl.h |  65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchTcoSmiDispatch.h          | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Register/PchRegs.h                    |  16 ++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Register/PchRegsLpc.h                 | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Register/PchRegsPsf.h                 |  50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Register/PchRegsPsth.h                |  66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 28 files changed, 3431 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/FlashProtectionConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/FlashProtectionConfig.h
new file mode 100644
index 0000000000..d1e10c3422
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/FlashProtectionConfig.h
@@ -0,0 +1,55 @@
+/** @file
+  FlashProtection policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _FLASH_PROTECTION_CONFIG_H_
+#define _FLASH_PROTECTION_CONFIG_H_
+
+#define FLASH_PROTECTION_CONFIG_REVISION 1
+extern EFI_GUID gFlashProtectionConfigGuid;
+
+#pragma pack (push,1)
+
+//
+// Flash Protection Range Register
+//
+#define PCH_FLASH_PROTECTED_RANGES         5
+
+/**
+  Protected Flash Range
+**/
+typedef struct {
+  UINT32                WriteProtectionEnable     :  1;     ///< Write or erase is blocked by hardware. <b>0: Disable</b>; 1: Enable.
+  UINT32                ReadProtectionEnable      :  1;     ///< Read is blocked by hardware. <b>0: Disable</b>; 1: Enable.
+  UINT32                RsvdBits                  :  30;    ///< Reserved
+  /**
+    The address of the upper limit of protection
+    This is a left shifted address by 12 bits with address bits 11:0 are assumed to be FFFh for limit comparison
+  **/
+  UINT16                ProtectedRangeLimit;
+  /**
+    The address of the upper limit of protection
+    This is a left shifted address by 12 bits with address bits 11:0 are assumed to be 0
+  **/
+  UINT16                ProtectedRangeBase;
+} PROTECTED_RANGE;
+
+/**
+  The PCH provides a method for blocking writes and reads to specific ranges
+  in the SPI flash when the Protected Ranges are enabled.
+  PROTECTED_RANGE is used to specify if flash protection are enabled,
+  the write protection enable bit and the read protection enable bit,
+  and to specify the upper limit and lower base for each register
+  Platform code is responsible to get the range base by PchGetSpiRegionAddresses routine,
+  and set the limit and base accordingly.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                                     ///< Config Block Header
+  PROTECTED_RANGE       ProtectRange[PCH_FLASH_PROTECTED_RANGES];   ///< Protected Flash Ranges
+} PCH_FLASH_PROTECTION_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _FLASH_PROTECTION_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/HsioConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/HsioConfig.h
new file mode 100644
index 0000000000..ec27845a48
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/HsioConfig.h
@@ -0,0 +1,57 @@
+/** @file
+  HSIO policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _HSIO_CONFIG_H_
+#define _HSIO_CONFIG_H_
+#define HSIO_PREMEM_CONFIG_REVISION 1 //@deprecated
+extern EFI_GUID gHsioPreMemConfigGuid; //@deprecated
+
+#define HSIO_CONFIG_REVISION 1
+extern EFI_GUID gHsioConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  The PCH_HSIO_PREMEM_CONFIG block provides HSIO message related settings.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header
+
+  /**
+  <b>(Test)</b>
+  0- Disable, disable will prevent the HSIO version check and ChipsetInit HECI message from being sent
+  <b>1- Enable</b> ChipsetInit HECI message
+  **/
+  UINT8     ChipsetInitMessage;
+  /**
+  <b>(Test)</b>
+  <b>0- Disable</b>
+  1- Enable When enabled, this is used to bypass the reset after ChipsetInit HECI message.
+  **/
+  UINT8     BypassPhySyncReset;
+  UINT8     RsvdBytes[2];
+
+} PCH_HSIO_PREMEM_CONFIG;
+
+
+/**
+  The PCH_HSIO_CONFIG block provides HSIO message related settings.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;         ///< Config Block Header
+  /**
+    Policy used to point to the Base (+ OEM) ChipsetInit binary used to sync between BIOS and CSME
+  **/
+  UINT32    ChipsetInitBinPtr;
+  /**
+    Policy used to indicate the size of the Base (+ OEM) ChipsetInit binary used to sync between BIOS and CSME
+  **/
+  UINT32    ChipsetInitBinLen;
+} PCH_HSIO_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _HSIO_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/HsioPcieConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/HsioPcieConfig.h
new file mode 100644
index 0000000000..bc23f3e1a6
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/HsioPcieConfig.h
@@ -0,0 +1,58 @@
+/** @file
+  HSIO pcie policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _HSIO_PCIE_CONFIG_H_
+#define _HSIO_PCIE_CONFIG_H_
+
+#include <PchLimits.h>
+
+#define HSIO_PCIE_PREMEM_CONFIG_REVISION 1
+extern EFI_GUID gHsioPciePreMemConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  The PCH_HSIO_PCIE_LANE_CONFIG describes HSIO settings for PCIe lane
+**/
+typedef struct {
+  //
+  // HSIO Rx Eq
+  // Refer to the EDS for recommended values.
+  // Note that these setting are per-lane and not per-port
+  //
+  UINT32  HsioRxSetCtleEnable           : 1;      ///< <b>0: Disable</b>; 1: Enable PCH PCIe Gen 3 Set CTLE Value
+  UINT32  HsioRxSetCtle                 : 6;      ///< PCH PCIe Gen 3 Set CTLE Value
+  UINT32  HsioTxGen1DownscaleAmpEnable  : 1;      ///< <b>0: Disable</b>; 1: Enable PCH PCIe Gen 1 TX Output Downscale Amplitude Adjustment value override
+  UINT32  HsioTxGen1DownscaleAmp        : 6;      ///< PCH PCIe Gen 1 TX Output Downscale Amplitude Adjustment value
+  UINT32  HsioTxGen2DownscaleAmpEnable  : 1;      ///< <b>0: Disable</b>; 1: Enable PCH PCIe Gen 2 TX Output Downscale Amplitude Adjustment value override
+  UINT32  HsioTxGen2DownscaleAmp        : 6;      ///< PCH PCIe Gen 2 TX Output Downscale Amplitude Adjustment value
+  UINT32  HsioTxGen3DownscaleAmpEnable  : 1;      ///< <b>0: Disable</b>; 1: Enable PCH PCIe Gen 3 TX Output Downscale Amplitude Adjustment value override
+  UINT32  HsioTxGen3DownscaleAmp        : 6;      ///< PCH PCIe Gen 3 TX Output Downscale Amplitude Adjustment value
+  UINT32  RsvdBits0                     : 4;      ///< Reserved Bits
+
+  UINT32  HsioTxGen1DeEmphEnable        : 1;      ///< <b>0: Disable</b>; 1: Enable PCH PCIe Gen 1 TX Output De-Emphasis Adjustment Setting value override
+  UINT32  HsioTxGen1DeEmph              : 6;      ///< PCH PCIe Gen 1 TX Output De-Emphasis Adjustment Setting
+  UINT32  HsioTxGen2DeEmph3p5Enable     : 1;      ///< <b>0: Disable</b>; 1: Enable PCH PCIe Gen 2 TX Output -3.5dB Mode De-Emphasis Adjustment Setting value override
+  UINT32  HsioTxGen2DeEmph3p5           : 6;      ///< PCH PCIe Gen 2 TX Output -3.5dB Mode De-Emphasis Adjustment Setting
+  UINT32  HsioTxGen2DeEmph6p0Enable     : 1;      ///< <b>0: Disable</b>; 1: Enable PCH PCIe Gen 2 TX Output -6.0dB Mode De-Emphasis Adjustment Setting value override
+  UINT32  HsioTxGen2DeEmph6p0           : 6;      ///< PCH PCIe Gen 2 TX Output -6.0dB Mode De-Emphasis Adjustment Setting
+  UINT32  RsvdBits1                     : 11;     ///< Reserved Bits
+} PCH_HSIO_PCIE_LANE_CONFIG;
+
+///
+/// The PCH_HSIO_PCIE_CONFIG block describes the configuration of the HSIO for PCIe lanes
+///
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  ///
+  /// These members describe the configuration of HSIO for PCIe lanes.
+  ///
+  PCH_HSIO_PCIE_LANE_CONFIG         Lane[PCH_MAX_PCIE_ROOT_PORTS];
+} PCH_HSIO_PCIE_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _HSIO_PCIE_LANE_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/HsioSataConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/HsioSataConfig.h
new file mode 100644
index 0000000000..21b0d7ff63
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/HsioSataConfig.h
@@ -0,0 +1,64 @@
+/** @file
+  Hsio Sata policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _HSIO_SATA_CONFIG_H_
+#define _HSIO_SATA_CONFIG_H_
+
+#define HSIO_SATA_PREMEM_CONFIG_REVISION 1
+extern EFI_GUID gHsioSataPreMemConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  The PCH_HSIO_SATA_PORT_LANE describes HSIO settings for SATA Port lane
+**/
+typedef struct {
+  //
+  // HSIO Rx Eq
+  //
+  UINT32  HsioRxGen1EqBoostMagEnable   : 1;       ///< <b>0: Disable</b>; 1: Enable Receiver Equalization Boost Magnitude Adjustment Value override
+  UINT32  HsioRxGen1EqBoostMag         : 6;       ///< SATA 1.5 Gb/sReceiver Equalization Boost Magnitude Adjustment value
+  UINT32  HsioRxGen2EqBoostMagEnable   : 1;       ///< <b>0: Disable</b>; 1: Enable Receiver Equalization Boost Magnitude Adjustment Value override
+  UINT32  HsioRxGen2EqBoostMag         : 6;       ///< SATA 3.0 Gb/sReceiver Equalization Boost Magnitude Adjustment value
+  UINT32  HsioRxGen3EqBoostMagEnable   : 1;       ///< <b>0: Disable</b>; 1: Enable Receiver Equalization Boost Magnitude Adjustment Value override
+  UINT32  HsioRxGen3EqBoostMag         : 6;       ///< SATA 6.0 Gb/sReceiver Equalization Boost Magnitude Adjustment value
+  //
+  // HSIO Tx Eq
+  //
+  UINT32  HsioTxGen1DownscaleAmpEnable : 1;       ///< <b>0: Disable</b>; 1: Enable SATA 1.5 Gb/s TX Output Downscale Amplitude Adjustment value override
+  UINT32  HsioTxGen1DownscaleAmp       : 6;       ///< SATA 1.5 Gb/s TX Output Downscale Amplitude Adjustment value
+  UINT32  RsvdBits0                    : 4;       ///< Reserved bits
+
+  UINT32  HsioTxGen2DownscaleAmpEnable : 1;       ///< <b>0: Disable</b>; 1: Enable SATA 3.0 Gb/s TX Output Downscale Amplitude Adjustment value override
+  UINT32  HsioTxGen2DownscaleAmp       : 6;       ///< SATA 3.0 Gb/s TX Output Downscale Amplitude Adjustment
+  UINT32  HsioTxGen3DownscaleAmpEnable : 1;       ///< <b>0: Disable</b>; 1: Enable SATA 6.0 Gb/s TX Output Downscale Amplitude Adjustment value override
+  UINT32  HsioTxGen3DownscaleAmp       : 6;       ///< SATA 6.0 Gb/s TX Output Downscale Amplitude Adjustment
+  UINT32  HsioTxGen1DeEmphEnable       : 1;       ///< <b>0: Disable</b>; 1: Enable SATA 1.5 Gb/s TX Output De-Emphasis Adjustment Setting value override
+  UINT32  HsioTxGen1DeEmph             : 6;       ///< SATA 1.5 Gb/s TX Output De-Emphasis Adjustment Setting
+
+  UINT32  HsioTxGen2DeEmphEnable       : 1;       ///< <b>0: Disable</b>; 1: Enable SATA 3.0 Gb/s TX Output De-Emphasis Adjustment Setting value override
+  UINT32  HsioTxGen2DeEmph             : 6;       ///< SATA 3.0 Gb/s TX Output De-Emphasis Adjustment Setting
+  UINT32  RsvdBits1                    : 4;       ///< Reserved bits
+
+  UINT32  HsioTxGen3DeEmphEnable       : 1;       ///< <b>0: Disable</b>; 1: Enable SATA 6.0 Gb/s TX Output De-Emphasis Adjustment Setting value override
+  UINT32  HsioTxGen3DeEmph             : 6;       ///< SATA 6.0 Gb/s TX Output De-Emphasis Adjustment Setting value override
+  UINT32  RsvdBits2                    : 25;      ///< Reserved bits
+} PCH_HSIO_SATA_PORT_LANE;
+
+///
+/// The PCH_HSIO_SATA_CONFIG block describes the HSIO configuration of the SATA controller.
+///
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  ///
+  /// These members describe the configuration of HSIO for SATA lanes.
+  ///
+  PCH_HSIO_SATA_PORT_LANE        PortLane[PCH_MAX_SATA_PORTS];
+} PCH_HSIO_SATA_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _HSIO_SATA_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/LockDownConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/LockDownConfig.h
new file mode 100644
index 0000000000..23f116cf3d
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/LockDownConfig.h
@@ -0,0 +1,61 @@
+/** @file
+  Lock down policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _LOCK_DOWN_CONFIG_H_
+#define _LOCK_DOWN_CONFIG_H_
+
+#define LOCK_DOWN_CONFIG_REVISION 1
+extern EFI_GUID gLockDownConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  The PCH_LOCK_DOWN_CONFIG block describes the expected configuration of the PCH
+  for security requirement.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  /**
+    <b>(Test)</b> Enable SMI_LOCK bit to prevent writes to the Global SMI Enable bit. 0: Disable; <b>1: Enable</b>.
+  **/
+  UINT32  GlobalSmi      :  1;
+  /**
+    <b>(Test)</b> Enable BIOS Interface Lock Down bit to prevent writes to the Backup Control Register
+    Top Swap bit and the General Control and Status Registers Boot BIOS Straps.
+    Intel strongly recommends that BIOS sets the BIOS Interface Lock Down bit. Enabling this bit
+    will mitigate malicious software attempts to replace the system BIOS with its own code.
+    0: Disable; <b>1: Enable</b>.
+  **/
+  UINT32  BiosInterface  :  1;
+  /**
+    Enable the BIOS Lock Enable (BLE) feature and set EISS bit (D31:F5:RegDCh[5])
+    for the BIOS region protection. When it is enabled, the BIOS Region can only be
+    modified from SMM.
+    If this EISS bit is set, then WPD must be a '1' and InSMM.STS must be '1' also
+    in order to write to BIOS regions of SPI Flash. If this EISS bit is clear,
+    then the InSMM.STS is a don't care.
+    The BIOS must set the EISS bit while BIOS Guard support is enabled.
+    In recovery path, platform can temporary disable EISS for SPI programming in
+    PEI phase or early DXE phase.
+    When PcdSmmVariableEnable is FALSE, to support BIOS regions update outside of SMM,
+    the BiosLock must be set to Disabled by platform.
+    0: Disable; <b>1: Enable.</b>
+  **/
+  UINT32  BiosLock       :  1;
+  /**
+    <b>(Test)</b> This test option when set will force all GPIO pads to be unlocked
+    before BIOS transitions to POSTBOOT_SAI. This option should not be enabled in production
+    configuration and used only for debug purpose when free runtime reconfiguration of
+    GPIO pads is needed.
+    <b>0: Disable</b>; 1: Enable.
+  **/
+  UINT32  UnlockGpioPads :  1;
+  UINT32  RsvdBits0      : 28;             ///< Reserved bits
+} PCH_LOCK_DOWN_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _LOCK_DOWN_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/LpcConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/LpcConfig.h
new file mode 100644
index 0000000000..3fc64aa056
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/LpcConfig.h
@@ -0,0 +1,38 @@
+/** @file
+  Lpc policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _LPC_CONFIG_H_
+#define _LPC_CONFIG_H_
+
+#define LPC_PREMEM_CONFIG_REVISION 1
+extern EFI_GUID gLpcPreMemConfigGuid;
+
+#pragma pack (push,1)
+
+/**
+  This structure contains the policies which are related to LPC.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  /**
+    Enhance the port 8xh decoding.
+    Original LPC only decodes one byte of port 80h, with this enhancement LPC can decode word or dword of port 80h-83h.
+    @note: this will occupy one LPC generic IO range register. While this is enabled, read from port 80h always return 0x00.
+    0: Disable, <b>1: Enable</b>
+  **/
+  UINT32    EnhancePort8xhDecoding      :  1;
+  /**
+   Hardware Autonomous Enable.
+   When enabled, LPC will automatically engage power gating when it has reached its idle condition.
+   0: Disable, <b>1: Enable</b>
+  **/
+  UINT32    LpcPmHAE                    :  1;
+  UINT32    RsvdBits                    : 30;     ///< Reserved bits
+} PCH_LPC_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _LPC_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/PchGeneralConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/PchGeneralConfig.h
new file mode 100644
index 0000000000..da77abc1b3
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/ConfigBlock/PchGeneralConfig.h
@@ -0,0 +1,72 @@
+/** @file
+  PCH General policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_GENERAL_CONFIG_H_
+#define _PCH_GENERAL_CONFIG_H_
+
+#define PCH_GENERAL_CONFIG_REVISION 1
+#define PCH_GENERAL_PREMEM_CONFIG_REVISION 2
+
+extern EFI_GUID gPchGeneralConfigGuid;
+extern EFI_GUID gPchGeneralPreMemConfigGuid;
+
+#pragma pack (push,1)
+
+enum PCH_RESERVED_PAGE_ROUTE {
+  PchReservedPageToLpc,                   ///< Port 80h cycles are sent to LPC.
+  PchReservedPageToPcie                   ///< Port 80h cycles are sent to PCIe.
+};
+
+/**
+  PCH General Configuration
+  <b>Revision 1</b>:  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  /**
+    This member describes whether or not the Compatibility Revision ID (CRID) feature
+    of PCH should be enabled. <b>0: Disable</b>; 1: Enable
+  **/
+  UINT32    Crid            :  1;
+  /**
+    Set to enable low latency of legacy IO.
+    Some systems require lower IO latency irrespective of power.
+    This is a tradeoff between power and IO latency.
+    @note: Once this is enabled, DmiAspm, Pcie DmiAspm in SystemAgent
+    and ITSS Clock Gating are forced to disabled.
+    <b>0: Disable</b>, 1: Enable
+  **/
+  UINT32    LegacyIoLowLatency  :  1;
+  UINT32    RsvdBits0           : 30;       ///< Reserved bits
+} PCH_GENERAL_CONFIG;
+
+/**
+  PCH General Pre-Memory Configuration
+  <b>Revision 1</b>:  - Initial version.
+  <b>Revision 2</b>:  - Added GpioOverride.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Config Block Header
+  /**
+    Control where the Port 80h cycles are sent, <b>0: LPC</b>; 1: PCI.
+  **/
+  UINT32    Port80Route     :  1;
+  UINT32    IotgPllSscEn    :  1;       ///< Need to disable CPU Side SSC for A0 PO
+  /**
+    Gpio override Level
+    -- <b>0: Disable</b>;
+    -  1: Override Level 1 - only skips GpioSetNativePadByFunction
+    -  2: Override Level 2 - skips GpioSetNativePadByFunction and GpioSetPadMode
+    Additional policy that allows GPIO configuration to be done by external means.
+    If equal to 1  PCH will skip every Pad configuration.
+  **/
+  UINT32    GpioOverride    :  3;
+  UINT32    RsvdBits0       : 27;       ///< Reserved bits
+} PCH_GENERAL_PREMEM_CONFIG;
+
+#pragma pack (pop)
+
+#endif // _PCH_GENERAL_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Library/PchCycleDecodingLib.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Library/PchCycleDecodingLib.h
new file mode 100644
index 0000000000..94509a80fe
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Library/PchCycleDecodingLib.h
@@ -0,0 +1,258 @@
+/** @file
+  Header file for PchCycleDecodingLib.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_CYCLE_DECODING_LIB_H_
+#define _PCH_CYCLE_DECODING_LIB_H_
+
+
+/**
+  Get PCH TCO base address.
+
+  @param[out] Address                   Address of TCO base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid pointer passed.
+**/
+EFI_STATUS
+PchTcoBaseGet (
+  OUT UINT16                            *Address
+  );
+
+///
+/// structure of LPC general IO range register
+/// It contains base address, address mask, and enable status.
+///
+typedef struct {
+  UINT32                                BaseAddr :16;
+  UINT32                                Length   :15;
+  UINT32                                Enable   : 1;
+} PCH_LPC_GEN_IO_RANGE;
+
+#define PCH_LPC_GEN_IO_RANGE_MAX        4
+#define ESPI_CS1_GEN_IO_RANGE_MAX       1
+
+///
+/// structure of LPC general IO range register list
+/// It lists all LPC general IO ran registers supported by PCH.
+///
+typedef struct {
+  PCH_LPC_GEN_IO_RANGE                  Range[PCH_LPC_GEN_IO_RANGE_MAX];
+} PCH_LPC_GEN_IO_RANGE_LIST;
+
+/**
+  Set PCH LPC/eSPI generic IO range.
+  For generic IO range, the base address must align to 4 and less than 0xFFFF, and the length must be power of 2
+  and less than or equal to 256. Moreover, the address must be length aligned.
+  This function basically checks the address and length, which should not overlap with all other generic ranges.
+  If no more generic range register available, it returns out of resource error.
+  This cycle decoding is also required on DMI side.
+  Some IO ranges below 0x100 have fixed target. The target might be ITSS,RTC,LPC,PMC or terminated inside P2SB
+  but all predefined and can't be changed. IO range below 0x100 will be rejected in this function except below ranges:
+    0x00-0x1F,
+    0x44-0x4B,
+    0x54-0x5F,
+    0x68-0x6F,
+    0x80-0x8F,
+    0xC0-0xFF
+  Steps of programming generic IO range:
+  1. Program LPC/eSPI PCI Offset 84h ~ 93h of Mask, Address, and Enable.
+  2. Program LPC/eSPI Generic IO Range in DMI
+
+  @param[in] Address                    Address for generic IO range base address.
+  @param[in] Length                     Length of generic IO range.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address or length passed.
+  @retval EFI_OUT_OF_RESOURCES          No more generic range available.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchLpcGenIoRangeSet (
+  IN  UINT16                            Address,
+  IN  UINTN                             Length
+  );
+
+/**
+  Set PCH LPC/eSPI memory range decoding.
+  This cycle decoding is required to be set on DMI side
+  Programming steps:
+  1. Program LPC PCI Offset 98h [0] to [0] to disable memory decoding first before changing base address.
+  2. Program LPC PCI Offset 98h [31:16, 0] to [Address, 1].
+  3. Program LPC Memory Range in DMI
+
+  @param[in] Address                    Address for memory base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address or length passed.
+  @retval EFI_OUT_OF_RESOURCES          No more generic range available.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchLpcMemRangeSet (
+  IN  UINT32                            Address
+  );
+
+/**
+  Set PCH eSPI CS1# memory range decoding.
+  This cycle decoding is required to be set on DMI side
+  Programming steps:
+  1. Program eSPI PCI Offset A8h (eSPI CS1#) [0] to [0] to disable memory decoding first before changing base address.
+  2. Program eSPI PCI Offset A8h (eSPI CS1#) [31:16, 0] to [Address, 1].
+  3. Program eSPI Memory Range in DMI
+
+  @param[in] Address                    Address for memory for decoding.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address or length passed.
+  @retval EFI_UNSUPPORTED               eSPI secondary slave not supported
+**/
+EFI_STATUS
+PchEspiCs1MemRangeSet (
+  IN  UINT32                            Address
+  );
+
+/**
+  Get PCH LPC/eSPI memory range decoding address.
+
+  @param[out] Address                   Address of LPC/eSPI memory decoding base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+**/
+EFI_STATUS
+PchLpcMemRangeGet (
+  OUT UINT32                            *Address
+  );
+
+/**
+  Get PCH eSPI CS1# memory range decoding address.
+
+  @param[out] Address                   Address of eSPI CS1# memory decoding base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+  @retval EFI_UNSUPPORTED               eSPI secondary slave not supported
+**/
+EFI_STATUS
+PchEspiCs1MemRangeGet (
+  OUT UINT32                            *Address
+  );
+
+/**
+  Set PCH BIOS range deocding.
+  This will check General Control and Status bit 10 (GCS.BBS) to identify SPI or LPC/eSPI and program BDE register accordingly.
+  Please check EDS for detail of BiosDecodeEnable bit definition.
+    bit 15: F8-FF Enable
+    bit 14: F0-F8 Enable
+    bit 13: E8-EF Enable
+    bit 12: E0-E8 Enable
+    bit 11: D8-DF Enable
+    bit 10: D0-D7 Enable
+    bit  9: C8-CF Enable
+    bit  8: C0-C7 Enable
+    bit  7: Legacy F Segment Enable
+    bit  6: Legacy E Segment Enable
+    bit  5: Reserved
+    bit  4: Reserved
+    bit  3: 70-7F Enable
+    bit  2: 60-6F Enable
+    bit  1: 50-5F Enable
+    bit  0: 40-4F Enable
+  This cycle decoding is allowed to set when DMIC.SRL is 0.
+  Programming steps:
+  1. if GCS.BBS is 0 (SPI), program SPI PCI offset D8h to BiosDecodeEnable.
+     if GCS.BBS is 1 (LPC/eSPi), program LPC/eSPI PCI offset D8h to BiosDecodeEnable.
+  2. program LPC/eSPI/SPI BIOS Decode Enable, PCR[DMI] + 2744h to the same value programmed in LPC/eSPI or SPI PCI Offset D8h.
+
+  @param[in] BiosDecodeEnable           Bios decode enable setting.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+**/
+EFI_STATUS
+PchBiosDecodeEnableSet (
+  IN  UINT16                            BiosDecodeEnable
+  );
+
+/**
+  Set PCH LPC IO decode ranges.
+  Program LPC I/O Decode Ranges, PCR[DMI] + 2770h[15:0] to the same value programmed in LPC offset 80h.
+  Please check EDS for detail of Lpc IO decode ranges bit definition.
+  Bit  12: FDD range
+  Bit 9:8: LPT range
+  Bit 6:4: ComB range
+  Bit 2:0: ComA range
+
+  @param[in] LpcIoDecodeRanges          Lpc IO decode ranges bit settings.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchLpcIoDecodeRangesSet (
+  IN  UINT16                            LpcIoDecodeRanges
+  );
+
+/**
+  Set PCH LPC and eSPI CS0# IO enable decoding.
+  Setup I/O Enables in DMI to the same value program in LPC/eSPI PCI offset 82h.
+  Note: Bit[15:10] of the source decode register is Read-Only. The IO range indicated by the Enables field
+  in LPC/eSPI PCI offset 82h[13:10] is always forwarded by DMI to subtractive agent for handling.
+  Please check EDS for detail of LPC/eSPI IO decode ranges bit definition.
+
+  @param[in] LpcIoEnableDecoding        LPC IO enable decoding bit settings.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchLpcIoEnableDecodingSet (
+  IN  UINT16                            LpcIoEnableDecoding
+  );
+
+/**
+  Set PCH eSPI CS1# IO enable decoding.
+  Setup I/O Enables in DMI to the same value program in eSPI PCI offset A0h (eSPI CS1#).
+  Note: Bit[15:10] of the source decode register is Read-Only. The IO range indicated by the Enables field
+  in eSPI PCI offset A0h[13:10] is always forwarded by DMI to subtractive agent for handling.
+  Please check EDS for detail of eSPI IO decode ranges bit definition.
+
+  @param[in] IoEnableDecoding           eSPI IO enable decoding bit settings.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMI configuration is locked
+**/
+EFI_STATUS
+PchEspiCs1IoEnableDecodingSet (
+  IN  UINT16                            IoEnableDecoding
+  );
+
+/**
+  Get IO APIC regsiters base address.
+
+  @param[out] IoApicBase                Buffer of IO APIC regsiter address
+
+  @retval EFI_SUCCESS                   Successfully completed.
+**/
+EFI_STATUS
+PchIoApicBaseGet (
+  OUT UINT32                            *IoApicBase
+  );
+
+/**
+  Get HPET base address.
+  This function will be unavailable after P2SB is hidden by PSF.
+
+  @param[out] HpetBase                  Buffer of HPET base address
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid offset passed.
+**/
+EFI_STATUS
+PchHpetBaseGet (
+  OUT UINT32                            *HpetBase
+  );
+
+#endif // _PCH_CYCLE_DECODING_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Library/PchInfoLib.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Library/PchInfoLib.h
new file mode 100644
index 0000000000..c8aee81a8b
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Library/PchInfoLib.h
@@ -0,0 +1,590 @@
+/** @file
+  Header file for PchInfoLib.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_INFO_LIB_H_
+#define _PCH_INFO_LIB_H_
+
+#include <Hda.h>
+#include <Uefi/UefiBaseType.h>
+
+typedef UINT8 PCH_STEPPING;
+
+typedef UINT8 PCH_SERIES;
+#define PCH_LP                  2
+
+typedef UINT8 PCH_GENERATION;
+#define TGL_PCH                 5
+
+typedef enum {
+  RstUnsupported  = 0,
+  RstPremium,
+  RstOptane,
+  RstMaxMode
+} RST_MODE;
+
+/**
+  Return Pch stepping type
+
+  @retval PCH_STEPPING            Pch stepping type
+**/
+PCH_STEPPING
+PchStepping (
+  VOID
+  );
+
+/**
+  Return Pch Series
+
+  @retval PCH_SERIES                Pch Series
+**/
+PCH_SERIES
+PchSeries (
+  VOID
+  );
+
+/**
+  Return Pch Generation
+
+  @retval PCH_GENERATION            Pch Generation
+**/
+PCH_GENERATION
+PchGeneration (
+  VOID
+  );
+
+/**
+  Check if this is TGL PCH generation
+
+  @retval TRUE                It's TGL PCH
+  @retval FALSE               It's not TGL PCH
+**/
+BOOLEAN
+IsTglPch (
+  VOID
+  );
+
+/**
+  Get Pch Maximum Pcie Root Port Number
+
+  @retval PcieMaxRootPort         Pch Maximum Pcie Root Port Number
+**/
+UINT8
+GetPchMaxPciePortNum (
+  VOID
+  );
+
+/**
+  Get Pch Maximum Pcie Controller Number
+
+  @retval Pch Maximum Pcie Controller Number
+**/
+UINT8
+GetPchMaxPcieControllerNum (
+  VOID
+  );
+
+/**
+  Get Pch Maximum Pcie Clock Number
+
+  @retval Pch Maximum Pcie Clock Number
+**/
+UINT8
+GetPchMaxPcieClockNum (
+  VOID
+  );
+
+/**
+  Get Pch Maximum Pcie ClockReq Number
+
+  @retval Pch Maximum Pcie ClockReq Number
+**/
+UINT8
+GetPchMaxPcieClockReqNum (
+  VOID
+  );
+
+/**
+  Get Pch Usb2 Maximum Physical Port Number
+
+  @retval Pch Usb2 Maximum Physical Port Number
+**/
+UINT8
+GetPchUsb2MaxPhysicalPortNum (
+  VOID
+  );
+
+/**
+  Get Pch Maximum Usb2 Port Number of XHCI Controller
+
+  @retval Pch Maximum Usb2 Port Number of XHCI Controller
+**/
+UINT8
+GetPchXhciMaxUsb2PortNum (
+  VOID
+  );
+
+/**
+  Get Pch Usb3 Maximum Physical Port Number
+
+  @retval Pch Usb3 Maximum Physical Port Number
+**/
+UINT8
+GetPchUsb3MaxPhysicalPortNum (
+  VOID
+  );
+
+/**
+  Get Pch Maximum Usb3 Port Number of XHCI Controller
+
+  @retval Pch Maximum Usb3 Port Number of XHCI Controller
+**/
+UINT8
+GetPchXhciMaxUsb3PortNum (
+  VOID
+  );
+
+/**
+  Get Pch Maximum Serial IO I2C controllers number
+
+  @retval Pch Maximum Serial IO I2C controllers number
+**/
+UINT8
+GetPchMaxSerialIoI2cControllersNum (
+  VOID
+  );
+
+/**
+  Get Pch Maximum Serial IO SPI controllers number
+
+  @retval Pch Maximum Serial IO SPI controllers number
+**/
+UINT8
+GetPchMaxSerialIoSpiControllersNum (
+  VOID
+  );
+
+/**
+  Get Pch Maximum Serial IO UART controllers number
+
+  @retval Pch Maximum Serial IO UART controllers number
+**/
+UINT8
+GetPchMaxSerialIoUartControllersNum (
+  VOID
+  );
+
+/**
+  Get Pch Maximum Serial IO SPI Chip Selects count
+
+  @retval Pch Maximum Serial IO SPI Chip Selects nu,ber
+**/
+UINT8
+GetPchMaxSerialIoSpiChipSelectsNum (
+  VOID
+  );
+
+/**
+  Get Pch Maximum ISH UART Controller number
+
+  @retval Pch Maximum ISH UART controllers number
+**/
+UINT8
+GetPchMaxIshUartControllersNum (
+  VOID
+  );
+
+/**
+  Get Pch Maximum ISH I2C Controller number
+
+  @retval Pch Maximum ISH I2C controllers number
+**/
+UINT8
+GetPchMaxIshI2cControllersNum (
+  VOID
+  );
+
+/**
+  Get Pch Maximum ISH I3C Controller number
+
+  @retval Pch Maximum ISH I3C controllers number
+**/
+UINT8
+GetPchMaxIshI3cControllersNum (
+  VOID
+  );
+
+/**
+  Get Pch Maximum ISH SPI Controller number
+
+  @retval Pch Maximum ISH SPI controllers number
+**/
+UINT8
+GetPchMaxIshSpiControllersNum (
+  VOID
+  );
+
+/**
+  Get Pch Maximum ISH SPI Controller Cs pins number
+
+  @retval Pch Maximum ISH SPI controller Cs pins number
+**/
+UINT8
+GetPchMaxIshSpiControllerCsPinsNum (
+  VOID
+  );
+
+/**
+  Get Pch Maximum ISH GP number
+
+  @retval Pch Maximum ISH GP number
+**/
+UINT8
+GetPchMaxIshGpNum (
+  VOID
+  );
+
+/**
+  Get Pch Maximum ME Applet count
+
+  @retval Pch Maximum ME Applet number
+**/
+UINT8
+GetPchMaxMeAppletCount (
+  VOID
+  );
+
+/**
+Get Pch Maximum ME Session count
+
+@retval Pch Maximum ME Sesion number
+**/
+UINT8
+GetPchMaxMeSessionCount(
+  VOID
+);
+
+/**
+  Get Pch Maximum Type C Port Number
+
+  @retval Pch Maximum Type C Port Number
+**/
+UINT8
+GetPchMaxTypeCPortNum (
+  VOID
+  );
+
+#define PCH_STEPPING_STR_LENGTH_MAX 3
+
+/**
+  Get PCH stepping ASCII string.
+  Function determines major and minor stepping versions and writes them into a buffer.
+  The return string is zero terminated
+
+  @param [out]     Buffer               Output buffer of string
+  @param [in]      BufferSize           Buffer size.
+                                        Must not be less then PCH_STEPPING_STR_LENGTH_MAX
+
+  @retval EFI_SUCCESS                   String copied successfully
+  @retval EFI_INVALID_PARAMETER         The stepping is not supported, or parameters are NULL
+  @retval EFI_BUFFER_TOO_SMALL          Input buffer size is too small
+**/
+EFI_STATUS
+PchGetSteppingStr (
+  OUT    CHAR8                          *Buffer,
+  IN     UINT32                         BufferSize
+  );
+
+/**
+  Get PCH series ASCII string.
+  The return string is zero terminated.
+
+  @retval Static ASCII string of PCH Series
+**/
+CHAR8*
+PchGetSeriesStr (
+  );
+
+/**
+  Check if this chipset supports eMMC controller
+
+  @retval BOOLEAN  TRUE if supported, FALSE otherwise
+**/
+BOOLEAN
+IsPchEmmcSupported (
+  VOID
+  );
+
+/**
+  Check if this chipset supports SD controller
+
+  @retval BOOLEAN  TRUE if supported, FALSE otherwise
+**/
+BOOLEAN
+IsPchSdCardSupported (
+  VOID
+  );
+
+/**
+  Check if this chipset supports THC controller
+
+  @retval BOOLEAN  TRUE if supported, FALSE otherwise
+**/
+BOOLEAN
+IsPchThcSupported (
+  VOID
+  );
+
+/**
+  Check if this chipset supports HSIO BIOS Sync
+
+  @retval BOOLEAN  TRUE if supported, FALSE otherwise
+**/
+BOOLEAN
+IsPchChipsetInitSyncSupported (
+  VOID
+  );
+
+/**
+  Gets the maximum number of UFS controller supported by this chipset.
+
+  @return Number of supported UFS controllers
+**/
+UINT8
+PchGetMaxUfsNum (
+  VOID
+  );
+
+/**
+  Check whether integrated LAN controller is supported.
+
+  @retval TRUE                    GbE is supported in PCH
+  @retval FALSE                   GbE is not supported by PCH
+**/
+BOOLEAN
+PchIsGbeSupported (
+  VOID
+  );
+
+/**
+  Check whether integrated TSN is supported.
+
+  @retval TRUE                    TSN is supported in current PCH
+  @retval FALSE                   TSN is not supported on current PCH
+**/
+BOOLEAN
+PchIsTsnSupported (
+  VOID
+  );
+
+/**
+  Check whether ISH is supported.
+
+  @retval TRUE                    ISH is supported in PCH
+  @retval FALSE                   ISH is not supported by PCH
+**/
+BOOLEAN
+PchIsIshSupported (
+  VOID
+  );
+
+/**
+  Check whether ATX Shutdown (PS_ON) is supported.
+
+  @retval    TRUE           ATX Shutdown (PS_ON) is supported in PCH
+  @retval    FALSE          ATX Shutdown (PS_ON) is not supported by PCH
+**/
+BOOLEAN
+IsPchPSOnSupported (
+  VOID
+  );
+
+/**
+  Get Pch Maximum Hda Sndw Link
+
+  @retval Pch Maximum Hda Sndw Link
+**/
+UINT8
+GetPchHdaMaxSndwLinkNum (
+  VOID
+  );
+
+/**
+  Get Pch Maximum Hda Ssp Link
+
+  @retval Pch Maximum Hda Ssp Link
+**/
+UINT8
+GetPchHdaMaxSspLinkNum (
+  VOID
+  );
+
+/**
+  Get Pch Maximum Hda Dmic Link
+
+  @retval Pch Maximum Hda Dmic Link
+**/
+UINT8
+GetPchHdaMaxDmicLinkNum (
+  VOID
+  );
+
+/**
+  Check if given Audio Interface is supported
+
+  @param[in] AudioLinkType   Link type support to be checked
+  @param[in] AudioLinkIndex  Link number
+
+  @retval    TRUE           Link supported
+  @retval    FALSE          Link not supported
+**/
+BOOLEAN
+IsAudioInterfaceSupported (
+  IN HDAUDIO_LINK_TYPE     AudioLinkType,
+  IN UINT32                AudioLinkIndex
+  );
+
+/**
+  Check if given Display Audio Link T-Mode is supported
+
+  @param[in] Tmode          T-mode support to be checked
+
+  @retval    TRUE           T-mode supported
+  @retval    FALSE          T-mode not supported
+**/
+BOOLEAN
+IsAudioIDispTmodeSupported (
+  IN HDAUDIO_IDISP_TMODE Tmode
+  );
+
+/**
+  Check if link between PCH and CPU is an P-DMI
+
+  @retval    TRUE           P-DMI link
+  @retval    FALSE          Not an P-DMI link
+**/
+BOOLEAN
+IsPchWithPdmi (
+  VOID
+  );
+
+/**
+  Check if link between PCH and CPU is an OP-DMI
+
+  @retval    TRUE           OP-DMI link
+  @retval    FALSE          Not an OP-DMI link
+**/
+BOOLEAN
+IsPchWithOpdmi (
+  VOID
+  );
+
+/**
+  Check if link between PCH and CPU is an F-DMI
+
+  @retval    TRUE           F-DMI link
+  @retval    FALSE          Not an F-DMI link
+**/
+BOOLEAN
+IsPchWithFdmi (
+  VOID
+  );
+
+/**
+  Get Pch Maximum THC count
+
+  @retval Pch Maximum THC count number
+**/
+UINT8
+GetPchMaxThcCount (
+  VOID
+  );
+
+typedef enum {
+  SataSosc125Mhz = 0,
+  SataSosc120Mhz,
+  SataSosc100Mhz,
+  SataSosc25Mhz,
+  SataSosc19p2Mhz,
+  SataSoscUnsupported
+} SATA_SOSC_CLK_FREQ;
+
+/**
+  Returns a frequency of the sosc_clk signal.
+  All SATA controllers on the system are assumed to
+  work on the same sosc_clk frequency.
+
+  @retval Frequency of the sosc_clk signal.
+**/
+SATA_SOSC_CLK_FREQ
+GetSataSoscClkFreq (
+  VOID
+  );
+
+/**
+  Check if SATA support should be awake after function disable
+
+  @retval    TRUE
+  @retval    FALSE
+**/
+BOOLEAN
+IsSataSupportWakeAfterFunctionDisable (
+  VOID
+  );
+
+
+//
+// USB2 PHY reference frequencies values (MHz)
+//
+typedef enum {
+  FREQ_19_2 = 0u,
+  FREQ_24_0,
+  FREQ_96_0,
+  FREQ_MAX
+} USB2_PHY_REF_FREQ;
+
+/**
+  Returns USB2 PHY Reference Clock frequency value used by PCH
+  This defines what electrical tuning parameters shall be used
+  during USB2 PHY initialization programming
+
+  @retval Frequency reference clock for USB2 PHY
+**/
+USB2_PHY_REF_FREQ
+GetUsb2PhyRefFreq (
+  VOID
+  );
+
+/**
+  return support status for P2SB PCR 20-bit addressing
+
+  @retval    TRUE
+  @retval    FALSE
+**/
+BOOLEAN
+IsP2sb20bPcrSupported (
+  VOID
+  );
+
+/**
+  Check if SPI in a given PCH generation supports an Extended BIOS Range Decode
+
+  @retval TRUE or FALSE if PCH supports Extended BIOS Range Decode
+**/
+BOOLEAN
+IsExtendedBiosRangeDecodeSupported (
+  VOID
+  );
+
+/**
+  Returns DMI target for current PCH SPI
+
+  @retval PCH SPI DMI target
+**/
+UINT16
+GetPchSpiDmiTarget (
+  VOID
+  );
+#endif // _PCH_INFO_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Library/PchPciBdfLib.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Library/PchPciBdfLib.h
new file mode 100644
index 0000000000..85456653de
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Library/PchPciBdfLib.h
@@ -0,0 +1,552 @@
+/** @file
+  Header file for PchPciBdfLib.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_PCI_BDF_LIB_H_
+#define _PCH_PCI_BDF_LIB_H_
+
+
+/**
+  Get eSPI controller address that can be passed to the PCI Segment Library functions.
+
+  @retval eSPI controller address in PCI Segment Library representation
+**/
+UINT64
+EspiPciCfgBase (
+  VOID
+  );
+
+/**
+  Get GbE controller address that can be passed to the PCI Segment Library functions.
+
+  @retval GbE controller address in PCI Segment Library representation
+**/
+UINT64
+GbePciCfgBase (
+  VOID
+  );
+
+/**
+  Returns Gigabit Ethernet PCI Device Number
+
+  @retval  GbE device number
+**/
+UINT8
+GbeDevNumber (
+  VOID
+  );
+
+/**
+  Returns Gigabit Ethernet PCI Function Number
+
+  @retval  GbE function number
+**/
+UINT8
+GbeFuncNumber (
+  VOID
+  );
+
+/**
+  Get HDA controller address that can be passed to the PCI Segment Library functions.
+
+  @retval HDA controller address in PCI Segment Library representation
+**/
+UINT64
+HdaPciCfgBase (
+  VOID
+  );
+
+/**
+  Get HDA PCI device number
+
+  @retval PCI dev number
+**/
+UINT8
+HdaDevNumber (
+  VOID
+  );
+
+/**
+  Get HDA PCI function number
+
+  @retval PCI fun number
+**/
+UINT8
+HdaFuncNumber (
+  VOID
+  );
+
+
+/**
+  Get P2SB controller address that can be passed to the PCI Segment Library functions.
+
+  @retval P2SB controller address in PCI Segment Library representation
+**/
+UINT64
+P2sbPciCfgBase (
+  VOID
+  );
+
+/**
+  Get P2SB PCI device number
+
+  @retval PCI dev number
+**/
+UINT8
+P2sbDevNumber (
+  VOID
+  );
+
+/**
+  Returns SPI PCI Config Space base address
+
+  @retval  UINT64  SPI Config Space base address
+**/
+UINT64
+SpiPciCfgBase (
+  VOID
+  );
+
+/**
+  Returns SPI Device number
+
+  @retval UINT8   PCH SPI Device number
+**/
+UINT8
+SpiDevNumber (
+  VOID
+  );
+
+/**
+  Returns SPI Function number
+
+  @retval UINT8   PCH SPI Function number
+**/
+UINT8
+SpiFuncNumber (
+  VOID
+  );
+
+/**
+  Get XHCI controller address that can be passed to the PCI Segment Library functions.
+
+  @retval XHCI controller address in PCI Segment Library representation
+**/
+UINT64
+PchXhciPciCfgBase (
+  VOID
+  );
+
+/**
+  Get XHCI controller PCIe Device Number
+
+  @retval XHCI controller PCIe Device Number
+**/
+UINT8
+PchXhciDevNumber (
+  VOID
+  );
+
+/**
+  Get XHCI controller PCIe Function Number
+
+  @retval XHCI controller PCIe Function Number
+**/
+UINT8
+PchXhciFuncNumber (
+  VOID
+  );
+
+/**
+  Get XDCI controller address that can be passed to the PCI Segment Library functions.
+
+  @retval XDCI controller address in PCI Segment Library representation
+**/
+UINT64
+PchXdciPciCfgBase (
+  VOID
+  );
+
+/**
+  Get XDCI controller PCIe Device Number
+
+  @retval XDCI controller PCIe Device Number
+**/
+UINT8
+PchXdciDevNumber (
+  VOID
+  );
+
+/**
+  Get XDCI controller PCIe Function Number
+
+  @retval XDCI controller PCIe Function Number
+**/
+UINT8
+PchXdciFuncNumber (
+  VOID
+  );
+
+/**
+  Get SMBUS controller address that can be passed to the PCI Segment Library functions.
+
+  @retval SMBUS controller address in PCI Segment Library representation
+**/
+UINT64
+SmbusPciCfgBase (
+  VOID
+  );
+
+/**
+  Return DMA Smbus Device Number
+
+  @retval DMA Smbus Device Number
+**/
+UINT8
+SmbusDmaDevNumber (
+  VOID
+  );
+
+/**
+  Return DMA Smbus Function Number
+
+  @retval  DMA Smbus Function Number
+**/
+UINT8
+SmbusDmaFuncNumber (
+  VOID
+  );
+
+/**
+  Get DMA SMBUS controller address that can be passed to the PCI Segment Library functions.
+
+  @retval DMA SMBUS controller address in PCI Segment Library representation
+**/
+UINT64
+SmbusDmaPciCfgBase (
+  VOID
+  );
+
+/**
+  Return Smbus Device Number
+
+  @retval Smbus Device Number
+**/
+UINT8
+SmbusDevNumber (
+  VOID
+  );
+
+/**
+  Return Smbus Function Number
+
+  @retval  Smbus Function Number
+**/
+UINT8
+SmbusFuncNumber (
+  VOID
+  );
+
+/**
+  Gets SATA controller PCIe config space base address
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval SATA controller PCIe config space base address
+**/
+UINT64
+SataPciCfgBase (
+  IN UINT32 SataCtrlIndex
+  );
+
+/**
+  Gets SATA controller PCIe Device Number
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval SATA controller PCIe Device Number
+**/
+UINT8
+SataDevNumber (
+  IN UINT32 SataCtrlIndex
+  );
+
+/**
+  Gets SATA controller PCIe Function Number
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval SATA controller PCIe Function Number
+**/
+UINT8
+SataFuncNumber (
+  IN UINT32 SataCtrlIndex
+  );
+
+/**
+  Returns PCH LPC device PCI base address.
+
+  @retval                   PCH LPC PCI base address.
+**/
+UINT64
+LpcPciCfgBase (
+  VOID
+  );
+
+/**
+  Get LPC controller PCIe Device Number
+
+  @retval LPC controller PCIe Device Number
+**/
+UINT8
+LpcDevNumber (
+  VOID
+  );
+
+/**
+  Get Thermal Device PCIe Device Number
+
+  @retval Thermal Device PCIe Device Number
+**/
+UINT8
+ThermalDevNumber (
+  VOID
+  );
+
+/**
+  Get Thermal Device PCIe Function Number
+
+  @retval Thermal Device PCIe Function Number
+**/
+UINT8
+ThermalFuncNumber (
+  VOID
+  );
+
+/**
+  Returns Thermal Device PCI base address.
+
+  @retval                   Thermal Device PCI base address.
+**/
+UINT64
+ThermalPciCfgBase (
+  VOID
+  );
+
+/**
+  Get LPC controller PCIe Function Number
+
+  @retval LPC controller PCIe Function Number
+**/
+UINT8
+LpcFuncNumber (
+  VOID
+  );
+
+/**
+  Get Serial IO I2C controller PCIe Device Number
+
+  @param[in]  I2cNumber       Serial IO I2C controller index
+
+  @retval Serial IO I2C controller PCIe Device Number
+**/
+UINT8
+SerialIoI2cDevNumber (
+  IN UINT8       I2cNumber
+  );
+
+/**
+  Get Serial IO I2C controller PCIe Function Number
+
+  @param[in]  I2cNumber       Serial IO I2C controller index
+
+  @retval Serial IO I2C controller PCIe Function Number
+**/
+UINT8
+SerialIoI2cFuncNumber (
+  IN UINT8       I2cNumber
+  );
+
+/**
+  Get Serial IO I2C controller address that can be passed to the PCI Segment Library functions.
+
+  @param[in]  I2cNumber       Serial IO I2C controller index
+
+  @retval Serial IO I2C controller address in PCI Segment Library representation
+**/
+UINT64
+SerialIoI2cPciCfgBase (
+  IN UINT8        I2cNumber
+  );
+
+/**
+  Get Serial IO SPI controller PCIe Device Number
+
+  @param[in]  I2cNumber       Serial IO SPI controller index
+
+  @retval Serial IO SPI controller PCIe Device Number
+**/
+UINT8
+SerialIoSpiDevNumber (
+  IN UINT8       SpiNumber
+  );
+
+/**
+  Get Serial IO SPI controller PCIe Function Number
+
+  @param[in]  SpiNumber       Serial IO SPI controller index
+
+  @retval Serial IO SPI controller PCIe Function Number
+**/
+UINT8
+SerialIoSpiFuncNumber (
+  IN UINT8       SpiNumber
+  );
+
+/**
+  Get Serial IO SPI controller address that can be passed to the PCI Segment Library functions.
+
+  @param[in]  SpiNumber       Serial IO SPI controller index
+
+  @retval Serial IO SPI controller address in PCI Segment Library representation
+**/
+UINT64
+SerialIoSpiPciCfgBase (
+  IN UINT8        SpiNumber
+  );
+
+/**
+  Get Serial IO UART controller PCIe Device Number
+
+  @param[in]  UartNumber       Serial IO UART controller index
+
+  @retval Serial IO UART controller PCIe Device Number
+**/
+UINT8
+SerialIoUartDevNumber (
+  IN UINT8       UartNumber
+  );
+
+/**
+  Get Serial IO UART controller PCIe Function Number
+
+  @param[in]  UartNumber       Serial IO UART controller index
+
+  @retval Serial IO UART controller PCIe Function Number
+**/
+UINT8
+SerialIoUartFuncNumber (
+  IN UINT8       UartNumber
+  );
+
+/**
+  Get Serial IO UART controller address that can be passed to the PCI Segment Library functions.
+
+  @param[in]  UartNumber       Serial IO UART controller index
+
+  @retval Serial IO UART controller address in PCI Segment Library representation
+**/
+UINT64
+SerialIoUartPciCfgBase (
+  IN UINT8        UartNumber
+  );
+
+/**
+  Get PCH PCIe controller PCIe Device Number
+
+  @param[in]  RpIndex       Root port physical number. (0-based)
+
+  @retval PCH PCIe controller PCIe Device Number
+**/
+UINT8
+PchPcieRpDevNumber (
+  IN  UINTN   RpIndex
+  );
+
+/**
+  Get PCH PCIe controller PCIe Function Number
+
+  @param[in]  RpIndex       Root port physical number. (0-based)
+
+  @retval PCH PCIe controller PCIe Function Number
+**/
+UINT8
+PchPcieRpFuncNumber (
+  IN  UINTN   RpIndex
+  );
+
+/**
+  Get PCH PCIe controller address that can be passed to the PCI Segment Library functions.
+
+  @param[in]  RpIndex       PCH PCIe Root Port physical number. (0-based)
+
+  @retval PCH PCIe controller address in PCI Segment Library representation
+**/
+UINT64
+PchPcieRpPciCfgBase (
+  IN  UINT32   RpIndex
+  );
+
+/**
+  Get HECI1 PCI device number
+
+  @retval PCI dev number
+**/
+UINT8
+PchHeci1DevNumber (
+  VOID
+  );
+
+/**
+  Get HECI1 PCI function number
+
+  @retval PCI fun number
+**/
+UINT8
+PchHeci1FuncNumber (
+  VOID
+  );
+
+/**
+  Get HECI1 controller address that can be passed to the PCI Segment Library functions.
+
+  @retval HECI1 controller address in PCI Segment Library representation
+**/
+UINT64
+PchHeci1PciCfgBase (
+  VOID
+  );
+
+/**
+  Get HECI3 PCI device number
+
+  @retval PCI dev number
+**/
+UINT8
+PchHeci3DevNumber (
+  VOID
+  );
+
+/**
+  Get HECI3 PCI function number
+
+  @retval PCI fun number
+**/
+UINT8
+PchHeci3FuncNumber (
+  VOID
+  );
+
+/**
+  Get HECI3 controller address that can be passed to the PCI Segment Library functions.
+
+  @retval HECI3 controller address in PCI Segment Library representation
+**/
+UINT64
+PchHeci3PciCfgBase (
+  VOID
+  );
+
+#endif //_PCH_PCI_BDF_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/PchInfoHob.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/PchInfoHob.h
new file mode 100644
index 0000000000..845bb19a65
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/PchInfoHob.h
@@ -0,0 +1,70 @@
+/** @file
+  This file contains definitions of PCH Info HOB.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_INFO_HOB_H_
+#define _PCH_INFO_HOB_H_
+
+extern EFI_GUID gPchInfoHobGuid;
+
+#define PCH_INFO_HOB_REVISION  4
+
+#pragma pack (push,1)
+/**
+  This structure is used to provide the information of PCH controller.
+
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Add CridSupport, CridOrgRid, and CridNewRid.
+  <b>Revision 3</b>:
+  - Add Thc0Strap.
+  <b>Revision 4</b>
+  - Removed GbePciePortNumber
+**/
+typedef struct {
+  /**
+    This member specifies the revision of the PCH Info HOB. This field is used
+    to indicate backwards compatible changes to the protocol. Platform code that
+    consumes this protocol must read the correct revision value to correctly interpret
+    the content of the protocol fields.
+  **/
+  UINT8        Revision;
+  UINT8        PcieControllerCfg[6];
+  /**
+    THC strap disable/enable status
+  **/
+  UINT8       Thc0Strap;
+  UINT32       PciePortFuses;
+  /**
+    Bit map for PCIe Root Port Lane setting. If bit is set it means that
+    corresponding Root Port has its lane enabled.
+    BIT0 - RP0, BIT1 - RP1, ...
+    This information needs to be passed through HOB as FIA registers
+    are not accessible with POSTBOOT_SAI
+  **/
+  UINT32       PciePortLaneEnabled;
+  /**
+    Publish Hpet BDF and IoApic BDF information for VTD.
+  **/
+  UINT32       HpetBusNum    :  8;
+  UINT32       HpetDevNum    :  5;
+  UINT32       HpetFuncNum   :  3;
+  UINT32       IoApicBusNum  :  8;
+  UINT32       IoApicDevNum  :  5;
+  UINT32       IoApicFuncNum :  3;
+  /**
+    Publish the CRID information.
+  **/
+  UINT32       CridOrgRid    :  8;
+  UINT32       CridNewRid    :  8;
+  UINT32       CridSupport   :  1;
+  UINT32       Rsvdbits      : 15;
+} PCH_INFO_HOB;
+
+#pragma pack (pop)
+
+#endif // _PCH_INFO_HOB_H_
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/PchLimits.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/PchLimits.h
new file mode 100644
index 0000000000..04ad17c8bd
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/PchLimits.h
@@ -0,0 +1,67 @@
+/** @file
+  Build time limits of PCH resources.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_LIMITS_H_
+#define _PCH_LIMITS_H_
+/*
+ * Defines povided in this file are indended to be used only where static value
+ * is needed. They are set to values which allow to accomodate multiple projects
+ * needs. Where runtime usage is possible please used dedicated functions from
+ * PchInfoLib to retrieve accurate values
+ */
+
+//
+// PCIe limits
+//
+#define PCH_MAX_PCIE_ROOT_PORTS             24
+#define PCH_MAX_PCIE_CONTROLLERS            6
+
+//
+// PCIe clocks limits
+//
+#define PCH_MAX_PCIE_CLOCKS                 16
+
+//
+// RST PCIe Storage Cycle Router limits
+//
+#define PCH_MAX_RST_PCIE_STORAGE_CR         3
+
+//
+// SATA limits
+//
+#define PCH_MAX_SATA_CONTROLLERS            3
+#define PCH_MAX_SATA_PORTS                  8
+
+//
+// SerialIo limits
+//
+#define PCH_MAX_SERIALIO_I2C_CONTROLLERS      8
+#define PCH_MAX_SERIALIO_SPI_CONTROLLERS      7
+#define PCH_MAX_SERIALIO_SPI_CHIP_SELECTS     2
+#define PCH_MAX_SERIALIO_UART_CONTROLLERS     7
+
+//
+// ISH limits
+//
+#define PCH_MAX_ISH_GP_PINS                   8
+#define PCH_MAX_ISH_UART_CONTROLLERS          2
+#define PCH_MAX_ISH_I2C_CONTROLLERS           3
+#define PCH_MAX_ISH_SPI_CONTROLLERS           1
+#define PCH_MAX_ISH_SPI_CS_PINS               1
+//
+// HDA limits
+//
+#define PCH_MAX_HDA_SDI                       2
+#define PCH_MAX_HDA_SSP_LINK_NUM              6
+#define PCH_MAX_HDA_SNDW_LINK_NUM             4
+
+//
+// Number of eSPI slaves
+//
+#define PCH_MAX_ESPI_SLAVES                  2
+
+#endif // _PCH_LIMITS_H_
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/PchPolicyCommon.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/PchPolicyCommon.h
new file mode 100644
index 0000000000..7b749818fa
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/PchPolicyCommon.h
@@ -0,0 +1,55 @@
+/** @file
+  PCH configuration based on PCH policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_POLICY_COMMON_H_
+#define _PCH_POLICY_COMMON_H_
+
+#include <ConfigBlock.h>
+#include <UsbConfig.h>
+#include <Usb2PhyConfig.h>
+#include <Usb3HsioConfig.h>
+
+#include "PchLimits.h"
+#include "ConfigBlock/PchGeneralConfig.h"
+#include <PchPcieRpConfig.h>
+#include <IoApicConfig.h>
+#include <SataConfig.h>
+#include <RstConfig.h>
+#include <PchDmiConfig.h>
+#include "ConfigBlock/FlashProtectionConfig.h"
+#include <InterruptConfig.h>
+#include <HdAudioConfig.h>
+#include <IshConfig.h>
+#include <GbeConfig.h>
+#include "ConfigBlock/LockDownConfig.h"
+#include "P2sbConfig.h"
+#include <PmConfig.h>
+#include <ScsConfig.h>
+#include <SerialIoConfig.h>
+#include <ThcConfig.h>
+#include <ThermalConfig.h>
+#include <EspiConfig.h>
+#include <CnviConfig.h>
+#include <IehConfig.h>
+#include <PsfConfig.h>
+#include <FivrConfig.h>
+#include <AdrConfig.h>
+#include <RtcConfig.h>
+#include <HybridStorageConfig.h>
+#include <SpiConfig.h>
+
+#ifndef FORCE_ENABLE
+#define FORCE_ENABLE  1
+#endif
+#ifndef FORCE_DISABLE
+#define FORCE_DISABLE 2
+#endif
+#ifndef PLATFORM_POR
+#define PLATFORM_POR  0
+#endif
+
+
+#endif // _PCH_POLICY_COMMON_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/PchPreMemPolicyCommon.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/PchPreMemPolicyCommon.h
new file mode 100644
index 0000000000..25e99d3a68
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/PchPreMemPolicyCommon.h
@@ -0,0 +1,56 @@
+/** @file
+  PCH configuration based on PCH policy
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_PREMEM_POLICY_COMMON_H_
+#define _PCH_PREMEM_POLICY_COMMON_H_
+
+#include <ConfigBlock.h>
+
+#include "PchLimits.h"
+#include "ConfigBlock/PchGeneralConfig.h"
+#include <DciConfig.h>
+#include <WatchDogConfig.h>
+#include <SmbusConfig.h>
+#include "ConfigBlock/LpcConfig.h"
+#include "ConfigBlock/HsioPcieConfig.h"
+#include "ConfigBlock/HsioSataConfig.h"
+#include "ConfigBlock/HsioConfig.h"
+
+#pragma pack (push,1)
+
+#ifndef FORCE_ENABLE
+#define FORCE_ENABLE  1
+#endif
+#ifndef FORCE_DISABLE
+#define FORCE_DISABLE 2
+#endif
+#ifndef PLATFORM_POR
+#define PLATFORM_POR  0
+#endif
+
+/**
+  PCH Policy revision number
+  Any backwards compatible changes to this structure will result in an update in the revision number
+**/
+#define PCH_PREMEM_POLICY_REVISION  1
+
+/**
+  PCH Policy PPI\n
+  All PCH config block change history will be listed here\n\n
+
+  - <b>Revision 1</b>:
+    - Initial version.\n
+**/
+typedef struct _PCH_PREMEM_POLICY {
+  CONFIG_BLOCK_TABLE_HEADER      TableHeader;
+/*
+  Individual Config Block Structures are added here in memory as part of AddConfigBlock()
+*/
+} PCH_PREMEM_POLICY;
+
+#pragma pack (pop)
+
+#endif // _PCH_PREMEM_POLICY_COMMON_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/PchResetPlatformSpecific.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/PchResetPlatformSpecific.h
new file mode 100644
index 0000000000..4573a11520
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/PchResetPlatformSpecific.h
@@ -0,0 +1,21 @@
+/** @file
+  PCH Reset Platform Specific definitions.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_RESET_PLATFORM_SPECIFIC_H_
+#define _PCH_RESET_PLATFORM_SPECIFIC_H_
+
+#define PCH_PLATFORM_SPECIFIC_RESET_STRING   L"PCH_RESET"
+#define PCH_RESET_DATA_STRING_MAX_LENGTH     (sizeof (PCH_PLATFORM_SPECIFIC_RESET_STRING) / sizeof (UINT16))
+
+extern EFI_GUID gPchGlobalResetGuid;
+
+typedef struct _RESET_DATA {
+  CHAR16   Description[PCH_RESET_DATA_STRING_MAX_LENGTH];
+  EFI_GUID Guid;
+} PCH_RESET_DATA;
+
+#endif // _PCH_RESET_PLATFORM_SPECIFIC_H_
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/IoTrapExDispatch.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/IoTrapExDispatch.h
new file mode 100644
index 0000000000..4d6241c32b
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/IoTrapExDispatch.h
@@ -0,0 +1,184 @@
+/** @file
+  PCH IO TrapEx Dispatch Protocol
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _IO_TRAP_EX_DISPATCH_H_
+#define _IO_TRAP_EX_DISPATCH_H_
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID                                       gIoTrapExDispatchProtocolGuid;
+
+typedef struct _IO_TRAP_EX_DISPATCH_PROTOCOL          IO_TRAP_EX_DISPATCH_PROTOCOL;
+
+/**
+  IO Trap Ex valid types
+**/
+typedef enum {
+  IoTrapExTypeWrite,
+  IoTrapExTypeRead,
+  IoTrapExTypeReadWrite,
+  IoTrapExTypeMaximum
+} IO_TRAP_EX_DISPATCH_TYPE;
+
+/**
+  IO Trap Ex context structure containing information about the
+  IO trap Ex event that should invoke the handler.
+  ByteEnableMask bitwise to ignore the ByteEnable setting. E.g. 1111b for any byte access.
+
+  Here are some examples for the usage.
+  1.  To trigger the TRAP for the IO address from 0x2000 to 0x20FF with BYTE/WORD/DWORD read/write access:
+      Address        = 0x2000
+      Length         = 0x100
+      Type           = IoTrapExTypeReadWrite
+      ByteEnable     = 0x00 (BE is not matter)
+      ByteEnableMask = 0x0F (BEM 0xF for any BYTE/WORD/DWORD access)
+  2.  To trigger the TRAP for port 0x61 with BYTE read access:
+      Address        = 0x60
+      Length         = 4
+      Type           = IoTrapExTypeRead
+      ByteEnable     = 0x02 (BE is 0010b to trap only second byte of every DWORD)
+      ByteEnableMask = 0x00 (BEM doesn't mask any BE bit)
+  3.  To trigger the TRAP for port 0x60 and 0x64 with BYTE write access:
+      Address        = 0x60
+      Length         = 8
+      Type           = IoTrapExTypeWrite
+      ByteEnable     = 0x01 (BE is 0001b to trap only first byte of every DWORD)
+      ByteEnableMask = 0x00 (BEM doesn't mask any BE bit)
+**/
+typedef struct {
+  /**
+    The Address must be dword alignment.
+  **/
+  UINT16                                Address;
+  UINT16                                Length;
+  IO_TRAP_EX_DISPATCH_TYPE              Type;
+  /**
+    Bitmap to enable trap for each byte of every dword alignment address.
+    The Io Trap Address must be dword alignment for ByteEnable.
+    E.g. 0001b for first byte, 0010b for second byte, 1100b for third and fourth byte.
+  **/
+  UINT8                                 ByteEnable;
+  /**
+    ByteEnableMask bitwise to ignore the ByteEnable setting. E.g. 1111b for any byte access.
+    The Io Trap Address must be dword alignment for ByteEnableMask.
+  **/
+  UINT8                                 ByteEnableMask;
+} IO_TRAP_EX_REGISTER_CONTEXT;
+
+/**
+  Callback function for an PCH IO TRAP EX handler dispatch.
+
+  @param[in] Address                    DWord-aligned address of the trapped cycle.
+  @param[in] ByteEnable                 This is the DWord-aligned byte enables associated with the trapped cycle.
+                                        A 1 in any bit location indicates that the corresponding byte is enabled in the cycle.
+  @param[in] WriteCycle                 TRUE = Write cycle; FALSE = Read cycle
+  @param[in] WriteData                  DWord of I/O write data. This field is undefined after trapping a read cycle.
+                                        The byte of WriteData is only valid if the corresponding bits in ByteEnable is 1.
+                                        E.g.
+                                        If ByteEnable is 0001b, then only first byte of WriteData is valid.
+                                        If ByteEnable is 0010b, then only second byte of WriteData is valid.
+**/
+typedef
+VOID
+(EFIAPI *IO_TRAP_EX_DISPATCH_CALLBACK) (
+  IN UINT16                             Address,
+  IN UINT8                              ByteEnable,
+  IN BOOLEAN                            WriteCycle,
+  IN UINT32                             WriteData
+  );
+
+/**
+  Register a new IO Trap Ex SMI dispatch function.
+  The caller will provide information of IO trap setting via the context.
+  Please consider to use EfiSmmIoTrapDispatch2Protocol as possible.
+  This is the function to extend the IoTrap capability, and it's expected
+  to handle the special ByteEnable and ByteEnableMask setting.
+  This register function will occupy one IoTrap register if possible.
+  And it only support one handler for one IoTrap event.
+  The Address of context MUST NOT be 0, and MUST be dword alignment.
+  The Length of context MUST not less than 4, and MUST be power of 2.
+  The ByteEnable and ByteEnableMask MUST not be zero at the same time.
+  if the IO Trap handler is not used. It also enable the IO Trap Range to generate
+  SMI.
+  Caller must take care of reserving the IO addresses in ACPI.
+
+  @param[in] This                 Pointer to the IO_TRAP_EX_DISPATCH_PROTOCOL instance.
+  @param[in] DispatchFunction     Pointer to dispatch function to be invoked for
+                                  this SMI source.
+  @param[in] RegisterContext      Pointer to the dispatch function's context.
+                                  The caller fills this context in before calling
+                                  the register function to indicate to the register
+                                  function the IO trap Ex SMI source for which the dispatch
+                                  function should be invoked.  This MUST not be NULL.
+  @param[out] DispatchHandle      Handle of dispatch function.
+
+  @retval EFI_SUCCESS             The dispatch function has been successfully
+                                  registered and the SMI source has been enabled.
+  @retval EFI_OUT_OF_RESOURCES    Insufficient resources are available
+  @retval EFI_INVALID_PARAMETER   Address requested is already in use.
+  @retval EFI_ACCESS_DENIED       Return access denied if the SmmReadyToLock event has been triggered
+**/
+typedef
+EFI_STATUS
+(EFIAPI *IO_TRAP_EX_DISPATCH_REGISTER) (
+  IN  IO_TRAP_EX_DISPATCH_PROTOCOL  *This,
+  IN  IO_TRAP_EX_DISPATCH_CALLBACK  DispatchFunction,
+  IN  IO_TRAP_EX_REGISTER_CONTEXT   *RegisterContext,
+  OUT EFI_HANDLE                    *DispatchHandle
+  );
+
+/**
+  Unregister a SMI source dispatch function.
+  This function is unsupported.
+
+  @param[in] This                 Pointer to the IO_TRAP_EX_DISPATCH_PROTOCOL instance.
+  @param[in] DispatchHandle       Handle of dispatch function to deregister.
+
+  @retval EFI_UNSUPPORTED         The function is unsupported.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *IO_TRAP_EX_DISPATCH_UNREGISTER) (
+  IN  IO_TRAP_EX_DISPATCH_PROTOCOL  *This,
+  IN  EFI_HANDLE                    DispatchHandle
+  );
+
+/**
+  Interface structure for the IO trap Extention protocol.
+  This protocol exposes full IO TRAP capability for ByteEnable and ByteEnableMask setting.
+  Platform code should fully control the ByteEnable and ByteEnableMake while using this protocol.
+
+  Please consider to use EfiSmmIoTrapDispatch2Protocol as possible.
+  This is the function to extend the IoTrap capability, and it's expected
+  to handle the special ByteEnable and ByteEnableMask setting.
+
+  The protocol is low level, It returns PSTH trapped cycle. This might not be safe for multithread
+  if more than one thread triggers the same IOTRAP at the same time.
+**/
+struct _IO_TRAP_EX_DISPATCH_PROTOCOL {
+  /**
+    Register function for PCH IO TRAP EX DISPATCH PROTOCOL.
+    The caller will provide information of IO trap setting via the context.
+    Please consider to use EfiSmmIoTrapDispatch2Protocol as possible.
+    This is the function to extend the IoTrap capability, and it's expected
+    to handle the special ByteEnable and ByteEnableMask setting.
+    This register function will occupy one IoTrap register if possible.
+    And it only support one handler for one IoTrap event.
+    The Address of context MUST NOT be 0, and MUST be dword alignment.
+    The Length of context MUST not less than 4, and MUST be power of 2.
+    The ByteEnable and ByteEnableMask MUST not be zero at the same time.
+    if the IO Trap handler is not used. It also enable the IO Trap Range to
+    generate SMI.
+  **/
+  IO_TRAP_EX_DISPATCH_REGISTER      Register;
+  /**
+    Unregister function for PCH IO TRAP EX DISPATCH PROTOCOL.
+  **/
+  IO_TRAP_EX_DISPATCH_UNREGISTER    UnRegister;
+};
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchAcpiSmiDispatch.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchAcpiSmiDispatch.h
new file mode 100644
index 0000000000..136734d9ff
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchAcpiSmiDispatch.h
@@ -0,0 +1,134 @@
+/** @file
+  APIs of PCH ACPI SMI Dispatch Protocol.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_ACPI_SMI_DISPATCH_PROTOCOL_H_
+#define _PCH_ACPI_SMI_DISPATCH_PROTOCOL_H_
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID                         gPchAcpiSmiDispatchProtocolGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _PCH_ACPI_SMI_DISPATCH_PROTOCOL    PCH_ACPI_SMI_DISPATCH_PROTOCOL;
+
+//
+// Member functions
+//
+
+/**
+  Callback function for an PCH ACPI SMI handler dispatch.
+
+  @param[in] DispatchHandle             The unique handle assigned to this handler by register function.
+
+**/
+typedef
+VOID
+(EFIAPI *PCH_ACPI_SMI_DISPATCH_CALLBACK) (
+  IN EFI_HANDLE                         DispatchHandle
+  );
+
+/**
+  Register a child SMI source dispatch function for PCH ACPI SMI events.
+
+  @param[in] This                       Protocol instance pointer.
+  @param[in] DispatchFunction           Pointer to dispatch function to be invoked for
+                                        this SMI source
+  @param[out] DispatchHandle            Handle of dispatch function, for when interfacing
+                                        with the parent SMM driver.
+
+  @retval EFI_SUCCESS                   The dispatch function has been successfully
+                                        registered and the SMI source has been enabled.
+  @retval EFI_DEVICE_ERROR              The driver was unable to enable the SMI source.
+  @retval EFI_OUT_OF_RESOURCES          Not enough memory (system or SMM) to manage this child.
+  @retval EFI_ACCESS_DENIED             Return access denied if the EndOfDxe event has been triggered
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_ACPI_SMI_DISPATCH_REGISTER) (
+  IN  PCH_ACPI_SMI_DISPATCH_PROTOCOL    *This,
+  IN  PCH_ACPI_SMI_DISPATCH_CALLBACK    DispatchFunction,
+  OUT EFI_HANDLE                        *DispatchHandle
+  );
+
+/**
+  Unregister a child SMI source dispatch function with a parent ACPI SMM driver
+
+  @param[in] This                       Protocol instance pointer.
+  @param[in] DispatchHandle             Handle of dispatch function to deregister.
+
+  @retval EFI_SUCCESS                   The dispatch function has been successfully
+                                        unregistered and the SMI source has been disabled
+                                        if there are no other registered child dispatch
+                                        functions for this SMI source.
+  @retval EFI_INVALID_PARAMETER         Handle is invalid.
+  @retval EFI_ACCESS_DENIED             Return access denied if the EndOfDxe event has been triggered
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_ACPI_SMI_DISPATCH_UNREGISTER) (
+  IN  PCH_ACPI_SMI_DISPATCH_PROTOCOL    *This,
+  IN  EFI_HANDLE                        DispatchHandle
+  );
+
+/**
+  Interface structure for PCH ACPI SMIs Dispatch Protocol
+  The PCH ACPI SMI DISPATCH PROTOCOL provides the ability to dispatch function for PCH ACPI related SMIs.
+  It contains SMI types of Pme, RtcAlarm, PmeB0, and Time overflow.
+**/
+struct _PCH_ACPI_SMI_DISPATCH_PROTOCOL {
+  /**
+    This member specifies the revision of this structure. This field is used to
+    indicate backwards compatible changes to the protocol.
+  **/
+  UINT8                                 Revision;
+  /**
+    Smi unregister function for PCH ACPI SMI DISPATCH PROTOCOL.
+  **/
+  PCH_ACPI_SMI_DISPATCH_UNREGISTER      UnRegister;
+  /**
+    Pme
+    The event is triggered by hardware when the PME# signal goes active.
+    Additionally, the event is only triggered when SCI_EN is not set.
+  **/
+  PCH_ACPI_SMI_DISPATCH_REGISTER        PmeRegister;
+  /**
+    PmeB0
+    The event is triggered PCH when any internal device with PCI Power Management
+    capabilities on bus 0 asserts the equivalent of the PME# signal.
+    Additionally, the event is only triggered when SCI_EN is not set.
+    The following are internal devices which can set this bit:
+    Intel HD Audio, Intel Management Engine "maskable" wake events, Integrated LAN,
+    SATA, xHCI, Intel SST
+  **/
+  PCH_ACPI_SMI_DISPATCH_REGISTER        PmeB0Register;
+  /**
+    RtcAlarm
+    The event is triggered by hardware when the RTC generates an alarm
+    (assertion of the IRQ8# signal).
+  **/
+  PCH_ACPI_SMI_DISPATCH_REGISTER        RtcAlarmRegister;
+  /**
+    TmrOverflow
+    The event is triggered any time bit 22 of the 24-bit timer goes high
+    (bits are numbered from 0 to 23).
+    This will occur every 2.3435 seconds. When the TMROF_EN bit (ABASE + 02h, bit 0) is set,
+    then the setting of the TMROF_STS bit will additionally generate an SMI#
+    Additionally, the event is only triggered when SCI_EN is not set.
+  **/
+  PCH_ACPI_SMI_DISPATCH_REGISTER        TmrOverflowRegister;
+};
+
+/**
+  PCH ACPI SMI dispatch revision number
+
+  Revision 1:   Initial version
+**/
+#define PCH_ACPI_SMI_DISPATCH_REVISION            1
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchEspiSmiDispatch.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchEspiSmiDispatch.h
new file mode 100644
index 0000000000..4ea48c3fcd
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchEspiSmiDispatch.h
@@ -0,0 +1,144 @@
+/** @file
+  SmmEspiDispatch Protocol
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_ESPI_SMI_DISPATCH_PROTOCOL_H_
+#define _PCH_ESPI_SMI_DISPATCH_PROTOCOL_H_
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gPchEspiSmiDispatchProtocolGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _PCH_ESPI_SMI_DISPATCH_PROTOCOL PCH_ESPI_SMI_DISPATCH_PROTOCOL;
+
+//
+// Member functions
+//
+
+/**
+  Callback function for an PCH eSPI SMI handler dispatch.
+
+  @param[in] DispatchHandle             The unique handle assigned to this handler by register function.
+**/
+typedef
+VOID
+(EFIAPI *PCH_ESPI_SMI_DISPATCH_CALLBACK) (
+  IN EFI_HANDLE DispatchHandle
+  );
+
+/**
+  Generic function to register different types of eSPI SMI types
+
+  @param[in]  This              Not used
+  @param[in]  DispatchFunction  The callback to execute
+  @param[out] DispatchHandle    The handle for this callback registration
+
+  @retval     EFI_SUCCESS       Registration successful
+  @retval     EFI_ACCESS_DENIED Return access denied if the EndOfDxe event has been triggered
+  @retval     others            Registration failed
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_ESPI_SMI_REGISTER) (
+  IN PCH_ESPI_SMI_DISPATCH_PROTOCOL *This,
+  IN PCH_ESPI_SMI_DISPATCH_CALLBACK DispatchFunction,
+  OUT EFI_HANDLE                    *DispatchHandle
+  );
+
+/**
+  eSPI SMI Dispatch Protocol instance to unregister a callback based on handle
+
+  @param[in]  This                    Not used
+  @param[in]  DispatchHandle          Handle acquired during registration
+
+  @retval     EFI_SUCCESS             Unregister successful
+  @retval     EFI_INVALID_PARAMETER   DispatchHandle is null
+  @retval     EFI_INVALID_PARAMETER   DispatchHandle's forward link has bad pointer
+  @retval     EFI_INVALID_PARAMETER   DispatchHandle does not exist in database
+  @retval     EFI_ACCESS_DENIED       Unregistration is done after end of DXE
+**/
+
+typedef
+EFI_STATUS
+(EFIAPI *PCH_ESPI_SMI_UNREGISTER) (
+  IN PCH_ESPI_SMI_DISPATCH_PROTOCOL *This,
+  IN EFI_HANDLE                     DispatchHandle
+  );
+
+/**
+  Interface structure for PCH eSPI SMIs Dispatch Protocol
+  The PCH ESPI SMI DISPATCH PROTOCOL provides the ability to dispatch function for PCH eSPI related SMIs.
+  It contains SMI types of BiosWr, EcAssertedVw, and eSPI Master asserted SMIs
+**/
+struct _PCH_ESPI_SMI_DISPATCH_PROTOCOL {
+  /**
+    This member specifies the revision of this structure. This field is used to
+    indicate backwards compatible changes to the protocol.
+  **/
+  UINT8                   Revision;
+  /**
+    Unregister eSPI SMI events
+  **/
+  PCH_ESPI_SMI_UNREGISTER UnRegister;
+  /**
+    Register a BIOS Write Protect event
+  **/
+  PCH_ESPI_SMI_REGISTER   BiosWrProtectRegister;
+  /**
+    Register a BIOS Write Report event
+  **/
+  PCH_ESPI_SMI_REGISTER   BiosWrReportRegister;
+  /**
+    Register a Peripheral Channel Non Fatal Error event
+  **/
+  PCH_ESPI_SMI_REGISTER   PcErrNonFatalRegister;
+  /**
+    Register a Peripheral Channel Fatal Error event
+  **/
+  PCH_ESPI_SMI_REGISTER   PcErrFatalRegister;
+  /**
+    Register a Virtual Wire Non Fatal Error event
+  **/
+  PCH_ESPI_SMI_REGISTER   VwErrNonFatalRegister;
+  /**
+    Register a Virtual Wire Fatal Error event
+  **/
+  PCH_ESPI_SMI_REGISTER   VwErrFatalRegister;
+  /**
+    Register a Flash Channel Non Fatal Error event
+  **/
+  PCH_ESPI_SMI_REGISTER   FlashErrNonFatalRegister;
+  /**
+    Register a Flash Channel Fatal Error event
+  **/
+  PCH_ESPI_SMI_REGISTER   FlashErrFatalRegister;
+  /**
+    Register a Link Error event
+  **/
+  PCH_ESPI_SMI_REGISTER   LnkErrType1Register;
+  /**
+    Register a SMI handler for Espi slaver
+    This routine will also lock down ESPI_SMI_LOCK bit after registration and prevent
+    this handler from unregistration.
+    On platform that supports more than 1 device through another chip select (SPT-H),
+    the SMI handler itself needs to inspect both the eSPI devices' interrupt status registers
+    (implementation specific for each Slave) in order to identify and service the cause.
+    After servicing it, it has to clear the Slaves' internal SMI# status registers
+  **/
+  PCH_ESPI_SMI_REGISTER   EspiSlaveSmiRegister;
+};
+
+/**
+  PCH ESPI SMI dispatch revision number
+
+  Revision 1:   Initial version
+**/
+#define PCH_ESPI_SMI_DISPATCH_REVISION            1
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchPcieSmiDispatch.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchPcieSmiDispatch.h
new file mode 100644
index 0000000000..b75b9ab45d
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchPcieSmiDispatch.h
@@ -0,0 +1,166 @@
+/** @file
+  APIs of PCH PCIE SMI Dispatch Protocol.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_PCIE_SMI_DISPATCH_PROTOCOL_H_
+#define _PCH_PCIE_SMI_DISPATCH_PROTOCOL_H_
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID                         gPchPcieSmiDispatchProtocolGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _PCH_PCIE_SMI_DISPATCH_PROTOCOL    PCH_PCIE_SMI_DISPATCH_PROTOCOL;
+
+typedef enum {
+  PchRpIndex0      = 0,
+  PchRpIndex1      = 1,
+  PchRpIndex2      = 2,
+  PchRpIndex3      = 3,
+  PchRpIndex4      = 4,
+  PchRpIndex5      = 5,
+  PchRpIndex6      = 6,
+  PchRpIndex7      = 7,
+  PchRpIndex8      = 8,
+  PchRpIndex9      = 9,
+  PchRpIndex10     = 10,
+  PchRpIndex11     = 11,
+  PchRpIndex12     = 12,
+  PchRpIndex13     = 13,
+  PchRpIndex14     = 14,
+  PchRpIndex15     = 15,
+  PchRpIndex16     = 16,
+  PchRpIndex17     = 17,
+  PchRpIndex18     = 18,
+  PchRpIndex19     = 19,
+  PchRpIndex20     = 20,
+  PchRpIndex21     = 21,
+  PchRpIndex22     = 22,
+  PchRpIndex23     = 23,
+  /**
+    Quantity of PCH and CPU PCIe ports, as well as their encoding in this enum, may change between
+    silicon generations and series. Do not assume that PCH port 0 will be always encoded by 0.
+    Instead, it is recommended to use (PchRpIndex0 + PchPortIndex) style to be forward-compatible
+  **/
+  CpuRpIndex0      = 0x40,
+  CpuRpIndex1      = 0x41,
+  CpuRpIndex2      = 0x42,
+  CpuRpIndex3      = 0x43
+} PCIE_COMBINED_RPINDEX;
+
+//
+// Member functions
+//
+
+typedef struct {
+  UINT8                                 RpIndex; ///< Root port index (0-based), 0: RP1, 1: RP2, n: RP(N+1)
+  UINT8                                 BusNum;  ///< Root port pci bus number
+  UINT8                                 DevNum;  ///< Root port pci device number
+  UINT8                                 FuncNum; ///< Root port pci function number
+} PCH_PCIE_SMI_RP_CONTEXT;
+
+/**
+  Callback function for an PCH PCIE RP SMI handler dispatch.
+
+  @param[in] DispatchHandle             The unique handle assigned to this handler by register function.
+  @param[in] RpContext                  Pointer of PCH PCIE Root Port context.
+
+**/
+typedef
+VOID
+(EFIAPI *PCH_PCIE_SMI_RP_DISPATCH_CALLBACK) (
+  IN EFI_HANDLE                         DispatchHandle,
+  IN PCH_PCIE_SMI_RP_CONTEXT            *RpContext
+  );
+
+/**
+  Register a child SMI source dispatch function for PCH PCIERP SMI events.
+
+  @param[in] This                       Protocol instance pointer.
+  @param[in] DispatchFunction           Pointer to dispatch function to be invoked for
+                                        this SMI source
+  @param[in] RpIndex                    Refer PCIE_COMBINED_RPINDEX for PCH RP index and CPU RP index.
+                                        0: RP1, 1: RP2, n: RP(N+1)
+  @param[out] DispatchHandle            Handle of dispatch function, for when interfacing
+                                        with the parent SMM driver.
+
+  @retval EFI_SUCCESS                   The dispatch function has been successfully
+                                        registered and the SMI source has been enabled.
+  @retval EFI_DEVICE_ERROR              The driver was unable to enable the SMI source.
+  @retval EFI_OUT_OF_RESOURCES          Not enough memory (system or SMM) to manage this child.
+  @retval EFI_ACCESS_DENIED             Return access denied if the EndOfDxe event has been triggered
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_PCIE_SMI_RP_DISPATCH_REGISTER) (
+  IN  PCH_PCIE_SMI_DISPATCH_PROTOCOL    *This,
+  IN  PCH_PCIE_SMI_RP_DISPATCH_CALLBACK DispatchFunction,
+  IN  UINTN                             RpIndex,
+  OUT EFI_HANDLE                        *DispatchHandle
+  );
+
+/**
+  Unregister a child SMI source dispatch function with a parent PCIE SMM driver
+
+  @param[in] This                       Protocol instance pointer.
+  @param[in] DispatchHandle             Handle of dispatch function to deregister.
+
+  @retval EFI_SUCCESS                   The dispatch function has been successfully
+                                        unregistered and the SMI source has been disabled
+                                        if there are no other registered child dispatch
+                                        functions for this SMI source.
+  @retval EFI_INVALID_PARAMETER         Handle is invalid.
+  @retval EFI_ACCESS_DENIED             Return access denied if the EndOfDxe event has been triggered
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_PCIE_SMI_DISPATCH_UNREGISTER) (
+  IN  PCH_PCIE_SMI_DISPATCH_PROTOCOL    *This,
+  IN  EFI_HANDLE                        DispatchHandle
+  );
+
+/**
+  Interface structure for PCH PCIE SMIs Dispatch Protocol
+  The PCH PCIE SMI DISPATCH PROTOCOL provides the ability to dispatch function for PCH PCIE related SMIs.
+  It contains SMI types of HotPlug, LinkActive, and Link EQ.
+**/
+struct _PCH_PCIE_SMI_DISPATCH_PROTOCOL {
+  /**
+    This member specifies the revision of this structure. This field is used to
+    indicate backwards compatible changes to the protocol.
+  **/
+  UINT8                                 Revision;
+  /**
+    Smi unregister function for PCH PCIE SMI DISPATCH PROTOCOL.
+  **/
+  PCH_PCIE_SMI_DISPATCH_UNREGISTER      UnRegister;
+  /**
+    PcieRpXHotPlug
+    The event is triggered when PCIE root port Hot-Plug Presence Detect.
+  **/
+  PCH_PCIE_SMI_RP_DISPATCH_REGISTER     HotPlugRegister;
+  /**
+    PcieRpXLinkActive
+    The event is triggered when Hot-Plug Link Active State Changed.
+  **/
+  PCH_PCIE_SMI_RP_DISPATCH_REGISTER     LinkActiveRegister;
+  /**
+    PcieRpXLinkEq
+    The event is triggered when Device Requests Software Link Equalization.
+  **/
+  PCH_PCIE_SMI_RP_DISPATCH_REGISTER     LinkEqRegister;
+};
+
+/**
+  PCH PCIE SMI dispatch revision number
+
+  Revision 1:   Initial version
+**/
+#define PCH_PCIE_SMI_DISPATCH_REVISION            1
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchPolicy.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchPolicy.h
new file mode 100644
index 0000000000..ba7cbdb23e
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchPolicy.h
@@ -0,0 +1,40 @@
+/** @file
+  Interface definition details between Pch and platform drivers during DXE phase.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_POLICY_H_
+#define _PCH_POLICY_H_
+
+#include <ConfigBlock.h>
+#include <Library/ConfigBlockLib.h>
+#include "../IncludePrivate/PchConfigHob.h"    // To Be corrected
+#include <Library/HobLib.h>
+
+extern EFI_GUID gPchPolicyProtocolGuid;
+
+#define PCH_POLICY_PROTOCOL_REVISION  1
+
+
+/**
+  PCH DXE Policy
+
+  The PCH_POLICY_PROTOCOL producer drvier is recommended to
+  set all the PCH_POLICY_PROTOCOL size buffer zero before init any member parameter,
+  this clear step can make sure no random value for those unknown new version parameters.
+
+  Make sure to update the Revision if any change to the protocol, including the existing
+  internal structure definations.\n
+  Note: Here revision will be bumped up when adding/removing any config block under this structure.\n
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_TABLE_HEADER      TableHeader;
+/*
+  Individual Config Block Structures are added here in memory as part of AddConfigBlock()
+*/
+} PCH_POLICY_PROTOCOL;
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchSmiDispatch.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchSmiDispatch.h
new file mode 100644
index 0000000000..12b5f8117b
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchSmiDispatch.h
@@ -0,0 +1,132 @@
+/** @file
+  APIs of PCH SMI Dispatch Protocol.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_SMI_DISPATCH_PROTOCOL_H_
+#define _PCH_SMI_DISPATCH_PROTOCOL_H_
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID                         gPchSmiDispatchProtocolGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _PCH_SMI_DISPATCH_PROTOCOL         PCH_SMI_DISPATCH_PROTOCOL;
+
+//
+// Member functions
+//
+
+/**
+  Callback function for an PCH SMI handler dispatch.
+
+  @param[in] DispatchHandle             The unique handle assigned to this handler by register function.
+
+**/
+typedef
+VOID
+(EFIAPI *PCH_SMI_DISPATCH_CALLBACK) (
+  IN EFI_HANDLE                         DispatchHandle
+  );
+
+/**
+  Register a child SMI source dispatch function for specific PCH SMI dispatch event.
+
+  @param[in] This                       Protocol instance pointer.
+  @param[in] DispatchFunction           Pointer to dispatch function to be invoked for
+                                        this SMI source
+  @param[out] DispatchHandle            Handle of dispatch function, for when interfacing
+                                        with the parent SMM driver.
+
+  @retval EFI_SUCCESS                   The dispatch function has been successfully
+                                        registered and the SMI source has been enabled.
+  @retval EFI_DEVICE_ERROR              The driver was unable to enable the SMI source.
+  @retval EFI_OUT_OF_RESOURCES          Not enough memory (system or SMM) to manage this child.
+  @retval EFI_ACCESS_DENIED             Return access denied if the EndOfDxe event has been triggered
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SMI_DISPATCH_REGISTER) (
+  IN  PCH_SMI_DISPATCH_PROTOCOL         *This,
+  IN  PCH_SMI_DISPATCH_CALLBACK         DispatchFunction,
+  OUT EFI_HANDLE                        *DispatchHandle
+  );
+
+/**
+  Unregister a child SMI source dispatch function with a parent SMM driver
+
+  @param[in] This                       Protocol instance pointer.
+  @param[in] DispatchHandle             Handle of dispatch function to deregister.
+
+  @retval EFI_SUCCESS                   The dispatch function has been successfully
+                                        unregistered and the SMI source has been disabled
+                                        if there are no other registered child dispatch
+                                        functions for this SMI source.
+  @retval EFI_INVALID_PARAMETER         Handle is invalid.
+  @retval EFI_ACCESS_DENIED             Return access denied if the EndOfDxe event has been triggered
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SMI_DISPATCH_UNREGISTER) (
+  IN  PCH_SMI_DISPATCH_PROTOCOL         *This,
+  IN  EFI_HANDLE                        DispatchHandle
+  );
+
+/**
+  Interface structure for PCH specific SMIs Dispatch Protocol
+  The PCH SMI DISPATCH PROTOCOL provides the ability to dispatch function for PCH misc SMIs.
+  It contains legacy SMIs and new PCH SMI types like:
+  SerialIrq, McSmi, Smbus, ...
+**/
+struct _PCH_SMI_DISPATCH_PROTOCOL {
+  /**
+    This member specifies the revision of this structure. This field is used to
+    indicate backwards compatible changes to the protocol.
+  **/
+  UINT8                                 Revision;
+  /**
+    Smi unregister function for PCH SMI DISPATCH PROTOCOL.
+  **/
+  PCH_SMI_DISPATCH_UNREGISTER           UnRegister;
+  /**
+    SerialIrq
+    The event is triggered while the SMI# was caused by the SERIRQ decoder.
+  **/
+  PCH_SMI_DISPATCH_REGISTER             SerialIrqRegister;
+  /**
+    McSmi
+    The event is triggered if there has been an access to the power management
+    microcontroller range (62h or 66h) and the Microcontroller Decode Enable #1 bit
+    in the LPC Bridge I/O Enables configuration register is 1 .
+  **/
+  PCH_SMI_DISPATCH_REGISTER             McSmiRegister;
+  /**
+    SmBus
+    The event is triggered while the SMI# was caused by:
+    1. The SMBus Slave receiving a message that an SMI# should be caused, or
+    2. The SMBALERT# signal goes active and the SMB_SMI_EN bit is set and the
+       SMBALERT_DIS bit is cleared, or
+    3. The SMBus Slave receiving a Host Notify message and the HOST_NOTIFY_INTREN and
+       the SMB_SMI_EN bits are set, or
+    4. The PCH detecting the SMLINK_SLAVE_SMI command while in the S0 state.
+  **/
+  PCH_SMI_DISPATCH_REGISTER             SmbusRegister;
+  /**
+    SPI Asynchronous
+    When registered, the flash controller will generate an SMI when it blocks a BIOS write or erase.
+  **/
+  PCH_SMI_DISPATCH_REGISTER             SpiAsyncRegister;
+};
+
+/**
+  PCH SMI dispatch revision number
+
+  Revision 1:   Initial version
+**/
+#define PCH_SMI_DISPATCH_REVISION                 1
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchSmmIoTrapControl.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchSmmIoTrapControl.h
new file mode 100644
index 0000000000..9f2793634e
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchSmmIoTrapControl.h
@@ -0,0 +1,65 @@
+/** @file
+  PCH SMM IO Trap Control Protocol
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_SMM_IO_TRAP_CONTROL_H_
+#define _PCH_SMM_IO_TRAP_CONTROL_H_
+
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID                                   gPchSmmIoTrapControlGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _PCH_SMM_IO_TRAP_CONTROL_PROTOCOL  PCH_SMM_IO_TRAP_CONTROL_PROTOCOL;
+
+//
+// Related Definitions
+//
+
+//
+// Member functions
+//
+
+/**
+  The Prototype of Pause and Resume IoTrap callback function.
+
+  @param[in] This                 Pointer to the PCH_SMM_IO_TRAP_CONTROL_PROTOCOL instance.
+  @param[in] DispatchHandle       Handle of the child service to change state.
+
+  @retval EFI_SUCCESS             This operation is complete.
+  @retval EFI_INVALID_PARAMETER   The DispatchHandle is invalid.
+  @retval EFI_ACCESS_DENIED       The SMI status is alrady PAUSED/RESUMED.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SMM_IO_TRAP_CONTROL_FUNCTION) (
+  IN PCH_SMM_IO_TRAP_CONTROL_PROTOCOL           * This,
+  IN EFI_HANDLE                                 DispatchHandle
+  );
+
+/**
+  Interface structure for the SMM IO trap pause and resume protocol
+  This protocol provides the functions to runtime control the IoTrap SMI enabled/disable.
+  This applys the capability to the DispatchHandle which returned by IoTrap callback
+  registration, and the DispatchHandle which must be MergeDisable = TRUE and Address != 0.
+  Besides, when S3 resuem, it only restores the state of IoTrap callback registration.
+  The Paused/Resume state won't be restored after S3 resume.
+**/
+struct _PCH_SMM_IO_TRAP_CONTROL_PROTOCOL {
+  /**
+    This runtime pauses a registered IoTrap handler.
+  **/
+  PCH_SMM_IO_TRAP_CONTROL_FUNCTION      Pause;
+  /**
+    This runtime resumes a registered IoTrap handler.
+  **/
+  PCH_SMM_IO_TRAP_CONTROL_FUNCTION      Resume;
+};
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchSmmPeriodicTimerControl.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchSmmPeriodicTimerControl.h
new file mode 100644
index 0000000000..a7b44c5f7e
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchSmmPeriodicTimerControl.h
@@ -0,0 +1,65 @@
+/** @file
+  PCH SMM Periodic Timer Control Protocol
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_SMM_PERIODIC_TIMER_CONTROL_H_
+#define _PCH_SMM_PERIODIC_TIMER_CONTROL_H_
+
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID                                             gPchSmmPeriodicTimerControlGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _PCH_SMM_PERIODIC_TIMER_CONTROL_PROTOCOL     PCH_SMM_PERIODIC_TIMER_CONTROL_PROTOCOL;
+
+//
+// Related Definitions
+//
+
+//
+// Member functions
+//
+
+/**
+  The Prototype of Pause and Resume SMM PERIODIC TIMER function.
+
+  @param[in] This                       Pointer to the PCH_SMM_PERIODIC_TIMER_CONTROL_PROTOCOL instance.
+  @param[in] DispatchHandle             Handle of the child service to change state.
+
+  @retval EFI_SUCCESS                   This operation is complete.
+  @retval EFI_INVALID_PARAMETER         The DispatchHandle is invalid.
+  @retval EFI_ACCESS_DENIED             The SMI status is alrady PAUSED/RESUMED.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SMM_PERIODIC_TIMER_CONTROL_FUNCTION) (
+  IN PCH_SMM_PERIODIC_TIMER_CONTROL_PROTOCOL      *This,
+  IN EFI_HANDLE                                   DispatchHandle
+  );
+
+/**
+  Interface structure for the SMM PERIODIC TIMER pause and resume protocol
+  This protocol provides the functions to runtime control the SM periodic timer enabled/disable.
+  This applies the capability to the DispatchHandle which returned by SMM periodic timer callback
+  registration.
+  Besides, when S3 resume, it only restores the state of callback registration.
+  The Paused/Resume state won't be restored after S3 resume.
+**/
+struct _PCH_SMM_PERIODIC_TIMER_CONTROL_PROTOCOL {
+  /**
+    This runtime pauses the registered periodic timer handler.
+  **/
+  PCH_SMM_PERIODIC_TIMER_CONTROL_FUNCTION         Pause;
+  /**
+    This runtime resumes the registered periodic timer handler.
+  **/
+  PCH_SMM_PERIODIC_TIMER_CONTROL_FUNCTION         Resume;
+};
+
+#endif // _PCH_SMM_PERIODIC_TIMER_CONTROL_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchTcoSmiDispatch.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchTcoSmiDispatch.h
new file mode 100644
index 0000000000..b443484f39
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Protocol/PchTcoSmiDispatch.h
@@ -0,0 +1,150 @@
+/** @file
+  APIs of PCH TCO SMI Dispatch Protocol.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_TCO_SMI_DISPATCH_PROTOCOL_H_
+#define _PCH_TCO_SMI_DISPATCH_PROTOCOL_H_
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID                         gPchTcoSmiDispatchProtocolGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _PCH_TCO_SMI_DISPATCH_PROTOCOL     PCH_TCO_SMI_DISPATCH_PROTOCOL;
+
+//
+// Member functions
+//
+
+/**
+  Callback function for an PCH TCO SMI handler dispatch.
+
+  @param[in] DispatchHandle             The unique handle assigned to this handler by register function.
+
+**/
+typedef
+VOID
+(EFIAPI *PCH_TCO_SMI_DISPATCH_CALLBACK) (
+  IN EFI_HANDLE                         DispatchHandle
+  );
+
+/**
+  Register a child SMI source dispatch function for PCH TCO SMI events.
+
+  @param[in] This                       Protocol instance pointer.
+  @param[in] DispatchFunction           Pointer to dispatch function to be invoked for
+                                        this SMI source
+  @param[out] DispatchHandle            Handle of dispatch function, for when interfacing
+                                        with the parent SMM driver.
+
+  @retval EFI_SUCCESS                   The dispatch function has been successfully
+                                        registered and the SMI source has been enabled.
+  @retval EFI_DEVICE_ERROR              The driver was unable to enable the SMI source.
+  @retval EFI_OUT_OF_RESOURCES          Not enough memory (system or SMM) to manage this child.
+  @retval EFI_ACCESS_DENIED             Return access denied if the EndOfDxe event has been triggered
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_TCO_SMI_DISPATCH_REGISTER) (
+  IN  PCH_TCO_SMI_DISPATCH_PROTOCOL     *This,
+  IN  PCH_TCO_SMI_DISPATCH_CALLBACK     DispatchFunction,
+  OUT EFI_HANDLE                        *DispatchHandle
+  );
+
+/**
+  Unregister a child SMI source dispatch function with a parent TCO SMM driver
+
+  @param[in] This                       Protocol instance pointer.
+  @param[in] DispatchHandle             Handle of dispatch function to deregister.
+
+  @retval EFI_SUCCESS                   The dispatch function has been successfully
+                                        unregistered and the SMI source has been disabled
+                                        if there are no other registered child dispatch
+                                        functions for this SMI source.
+  @retval EFI_INVALID_PARAMETER         Handle is invalid.
+  @retval EFI_ACCESS_DENIED             Return access denied if the EndOfDxe event has been triggered
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_TCO_SMI_DISPATCH_UNREGISTER) (
+  IN  PCH_TCO_SMI_DISPATCH_PROTOCOL     *This,
+  IN  EFI_HANDLE                        DispatchHandle
+  );
+
+/**
+  Interface structure for PCH TCO SMIs Dispatch Protocol
+  The PCH TCO SMI DISPATCH PROTOCOL provides the ability to dispatch function for PCH TCO related SMIs.
+  It contains SMI types of Mch, TcoTimeout, OsTco, Nmi, IntruderDectect, and BiowWp.
+**/
+struct _PCH_TCO_SMI_DISPATCH_PROTOCOL {
+  /**
+    This member specifies the revision of this structure. This field is used to
+    indicate backwards compatible changes to the protocol.
+  **/
+  UINT8                                 Revision;
+  /**
+    Smi unregister function for PCH TCO SMI DISPATCH PROTOCOL.
+  **/
+  PCH_TCO_SMI_DISPATCH_UNREGISTER       UnRegister;
+  /**
+    Mch
+    The event is triggered when PCH received a DMI special cycle message using DMI indicating that
+    it wants to cause an SMI.
+    The software must read the processor to determine the reason for the SMI.
+  **/
+  PCH_TCO_SMI_DISPATCH_REGISTER         MchRegister;
+  /**
+    TcoTimeout
+    The event is triggered by PCH to indicate that the SMI was caused by the TCO timer reaching 0.
+  **/
+  PCH_TCO_SMI_DISPATCH_REGISTER         TcoTimeoutRegister;
+  /**
+    OsTco
+    The event is triggered when software caused an SMI# by writing to the TCO_DAT_IN register (TCOBASE + 02h).
+  **/
+  PCH_TCO_SMI_DISPATCH_REGISTER         OsTcoRegister;
+  /**
+    Nmi
+    The event is triggered by the PCH when an SMI# occurs because an event occurred that would otherwise have
+    caused an NMI (because NMI2SMI_EN is set)
+  **/
+  PCH_TCO_SMI_DISPATCH_REGISTER         NmiRegister;
+  /**
+    IntruderDectect
+    The event is triggered by PCH to indicate that an intrusion was detected.
+  **/
+  PCH_TCO_SMI_DISPATCH_REGISTER         IntruderDetRegister;
+  /**
+    SpiBiosWp
+    This event is triggered when SMI# was caused by the TCO logic and
+    SPI flash controller asserted Synchronous SMI by BIOS lock enable set.
+  **/
+  PCH_TCO_SMI_DISPATCH_REGISTER         SpiBiosWpRegister;
+  /**
+    LpcBiosWp
+    This event is triggered when SMI# was caused by the TCO logic and
+    LPC/eSPI BIOS lock enable set.
+  **/
+  PCH_TCO_SMI_DISPATCH_REGISTER         LpcBiosWpRegister;
+  /**
+    NewCentury
+    This event is triggered when SMI# was caused by the TCO logic and
+    year of RTC date rolls over a century (99 to 00).
+  **/
+  PCH_TCO_SMI_DISPATCH_REGISTER         NewCenturyRegister;
+};
+
+/**
+  PCH TCO SMI dispatch revision number
+
+  Revision 1:   Initial version
+  Revision 2:   Add NEWCENTURY support
+**/
+#define PCH_TCO_SMI_DISPATCH_REVISION             2
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Register/PchRegs.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Register/PchRegs.h
new file mode 100644
index 0000000000..679cb17f6c
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Register/PchRegs.h
@@ -0,0 +1,16 @@
+/** @file
+  Generic register definitions for PCH.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_REGS_H_
+#define _PCH_REGS_H_
+
+///
+/// The default PCH PCI segment and bus number
+///
+#define DEFAULT_PCI_SEGMENT_NUMBER_PCH  0
+#define DEFAULT_PCI_BUS_NUMBER_PCH      0
+
+#endif //_PCH_REGS_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Register/PchRegsLpc.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Register/PchRegsLpc.h
new file mode 100644
index 0000000000..32dd88be0e
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Register/PchRegsLpc.h
@@ -0,0 +1,145 @@
+/** @file
+  Register names for PCH LPC/eSPI device
+
+Conventions:
+
+  - Register definition format:
+    Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpace_RegisterName
+  - Prefix:
+    Definitions beginning with "R_" are registers
+    Definitions beginning with "B_" are bits within registers
+    Definitions beginning with "V_" are meaningful values within the bits
+    Definitions beginning with "S_" are register size
+    Definitions beginning with "N_" are the bit position
+  - [GenerationName]:
+    Three letter acronym of the generation is used (e.g. SKL,KBL,CNL etc.).
+    Register name without GenerationName applies to all generations.
+  - [ComponentName]:
+    This field indicates the component name that the register belongs to (e.g. PCH, SA etc.)
+    Register name without ComponentName applies to all components.
+    Register that is specific to -LP denoted by "_PCH_LP_" in component name.
+  - SubsystemName:
+    This field indicates the subsystem name of the component that the register belongs to
+    (e.g. PCIE, USB, SATA, GPIO, PMC etc.).
+  - RegisterSpace:
+    MEM - MMIO space register of subsystem.
+    IO  - IO space register of subsystem.
+    PCR - Private configuration register of subsystem.
+    CFG - PCI configuration space register of subsystem.
+  - RegisterName:
+    Full register name.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_REGS_LPC_H_
+#define _PCH_REGS_LPC_H_
+
+#define B_LPC_CFG_DID         0xFFE0
+
+//
+// PCI to LPC Bridge Registers
+//
+
+#define R_LPC_CFG_IOD                             0x80
+#define V_LPC_CFG_IOD_COMB_2F8                    1
+#define V_LPC_CFG_IOD_COMA_3F8                    0
+#define V_LPC_CFG_IOD_COMA_2F8                    1
+#define R_LPC_CFG_IOE                             0x82
+#define B_LPC_CFG_IOE_SE                          BIT12           ///< Super I/O Enable, Enables decoding of I/O locations 2Eh and 2Fh to LPC.
+#define B_LPC_CFG_IOE_KE                          BIT10           ///< Keyboard Enable, Enables decoding of the keyboard I/O locations 60h and 64h to LPC.
+#define B_LPC_CFG_IOE_PPE                         BIT2            ///< Parallel Port Enable, Enables decoding of the LPT range to LPC. Range is selected by LIOD.LPT.
+#define B_LPC_CFG_IOE_CBE                         BIT1            ///< Com Port B Enable, Enables decoding of the COMB range to LPC. Range is selected LIOD.CB.
+#define B_LPC_CFG_IOE_CAE                         BIT0            ///< Com Port A Enable, Enables decoding of the COMA range to LPC. Range is selected LIOD.CA.
+#define R_LPC_CFG_ULKMC                           0x94
+#define B_LPC_CFG_ULKMC_A20PASSEN                 BIT5
+#define B_LPC_CFG_ULKMC_64WEN                     BIT3
+#define B_LPC_CFG_ULKMC_64REN                     BIT2
+#define B_LPC_CFG_ULKMC_60WEN                     BIT1
+#define B_LPC_CFG_ULKMC_60REN                     BIT0
+#define R_LPC_CFG_LGMR                            0x98
+#define B_LPC_CFG_LGMR_MA                         0xFFFF0000
+#define B_LPC_CFG_LGMR_LMRD_EN                    BIT0
+#define R_ESPI_CFG_CS1IORE                        0xA0
+#define R_ESPI_CFG_CS1GMR1                        0xA8
+
+#define R_LPC_CFG_BDE                             0xD8                          ///< BIOS decode enable
+
+//
+// APM Registers
+//
+#define R_PCH_IO_APM_CNT                             0xB2
+#define R_PCH_IO_APM_STS                             0xB3
+
+#define R_LPC_CFG_BC                              0xDC            ///< Bios Control
+#define S_LPC_CFG_BC                              1
+#define N_LPC_CFG_BC_LE                           1
+#define B_LPC_CFG_BC_WPD                          BIT0            ///< Write Protect Disable
+
+#define R_ESPI_CFG_PCBC                           0xDC            ///< Peripheral Channel BIOS Control
+#define S_ESPI_CFG_PCBC                           4               ///< Peripheral Channel BIOS Control register size
+#define B_ESPI_CFG_PCBC_BWRE                      BIT11           ///< BIOS Write Report Enable
+#define B_ESPI_CFG_PCBC_BWRS                      BIT10           ///< BIOS Write Report Status
+#define B_ESPI_CFG_PCBC_BWPDS                     BIT8            ///< BIOS Write Protect Disable Status
+#define N_ESPI_CFG_PCBC_BWPDS                     8               ///< BIOS Write Protect Disable Status bit position
+#define B_ESPI_CFG_PCBC_ESPI_EN                   BIT2            ///< eSPI Enable Pin Strap
+#define B_ESPI_CFG_PCBC_LE                        BIT1            ///< Lock Enable
+#define N_ESPI_CFG_PCBC_LE                        1
+
+//
+// eSPI slave registers
+//
+#define B_ESPI_SLAVE_BME                          BIT2            ///< Bus Master Enable
+
+//
+// Reset Generator I/O Port
+//
+#define R_PCH_IO_RST_CNT                             0xCF9
+#define V_PCH_IO_RST_CNT_FULLRESET                   0x0E
+#define V_PCH_IO_RST_CNT_HARDRESET                   0x06
+
+//
+// eSPI PCR Registers
+//
+#define R_ESPI_PCR_SLV_CFG_REG_CTL            0x4000                  ///< Slave Configuration Register and Link Control
+#define B_ESPI_PCR_SLV_CFG_REG_CTL_SCRE       BIT31                   ///< Slave Configuration Register Access Enable
+#define B_ESPI_PCR_SLV_CFG_REG_CTL_SCRS       (BIT30 | BIT29 | BIT28) ///< Slave Configuration Register Access Status
+#define N_ESPI_PCR_SLV_CFG_REG_CTL_SCRS       28                      ///< Slave Configuration Register Access Status bit position
+#define B_ESPI_PCR_SLV_CFG_REG_CTL_SBLCL      BIT27                   ///< IOSF-SB eSPI Link Configuration Lock
+#define V_ESPI_PCR_SLV_CFG_REG_CTL_SCRS_NOERR 7                       ///< No errors (transaction completed successfully)
+#define B_ESPI_PCR_SLV_CFG_REG_CTL_SID        (BIT20 | BIT19)         ///< Slave ID
+#define N_ESPI_PCR_SLV_CFG_REG_CTL_SID        19                      ///< Slave ID bit position
+#define B_ESPI_PCR_SLV_CFG_REG_CTL_SCRT       (BIT17 | BIT16)         ///< Slave Configuration Register Access Type
+#define N_ESPI_PCR_SLV_CFG_REG_CTL_SCRT       16                      ///< Slave Configuration Register Access Type bit position
+#define B_ESPI_PCR_SLV_CFG_REG_CTL_SCRA       0x00000FFF              ///< Slave Configuration Register Address
+#define R_ESPI_PCR_SLV_CFG_REG_DATA           0x4004                  ///< Slave Configuration Register Data
+
+#define R_ESPI_PCR_PCERR_SLV0                 0x4020          ///< Peripheral Channel Error for Slave 0
+#define B_ESPI_PCR_PCERR_PCURD                BIT24           ///< Peripheral Channel Unsupported Request Detected
+#define R_ESPI_PCR_VWERR_SLV0                 0x4030          ///< Virtual Wire Channel Error for Slave 0
+#define R_ESPI_PCR_FCERR_SLV0                 0x4040          ///< Flash Access Channel Error for Slave 0
+#define B_ESPI_PCR_FCERR_SAFBLK               BIT17           ///< SAF Blocked (SAFBLK)
+#define B_ESPI_PCR_XERR_XNFEE                 (BIT14 | BIT13) ///< Non-Fatal Error Reporting Enable bits
+#define N_ESPI_PCR_XERR_XNFEE                 13              ///< Non-Fatal Error Reporting Enable bit position
+#define V_ESPI_PCR_XERR_XNFEE_SMI             3               ///< Enable Non-Fatal Error Reporting as SMI
+#define B_ESPI_PCR_XERR_XNFES                 BIT12           ///< Fatal Error Status
+#define B_ESPI_PCR_XERR_XFEE                  (BIT6 | BIT5)   ///< Fatal Error Reporting Enable bits
+#define N_ESPI_PCR_XERR_XFEE                  5               ///< Fatal Error Reporting Enable bit position
+#define V_ESPI_PCR_XERR_XFEE_SMI              3               ///< Enable Fatal Error Reporting as SMI
+#define B_ESPI_PCR_XERR_XFES                  BIT4            ///< Fatal Error Status
+#define S_ESPI_PCR_XERR                       4               ///< Channel register sizes
+#define B_ESPI_PCR_PCERR_SLV0_PCURD           BIT24           ///< Peripheral Channel Unsupported Request Detected
+#define R_ESPI_PCR_LNKERR_SLV0                0x4050          ///< Link Error for Slave 0
+#define S_ESPI_PCR_LNKERR_SLV0                4               ///< Link Error for Slave 0 register size
+#define B_ESPI_PCR_LNKERR_SLV0_SLCRR          BIT31           ///< eSPI Link and Slave Channel Recovery Required
+#define B_ESPI_PCR_LNKERR_SLV0_LFET1E         (BIT22 | BIT21) ///< Fatal Error Type 1 Reporting Enable
+#define N_ESPI_PCR_LNKERR_SLV0_LFET1E         21              ///< Fatal Error Type 1 Reporting Enable bit position
+#define V_ESPI_PCR_LNKERR_SLV0_LFET1E_SMI     3               ///< Enable Fatal Error Type 1 Reporting as SMI
+#define B_ESPI_PCR_LNKERR_SLV0_LFET1S         BIT20           ///< Link Fatal Error Type 1 Status
+#define R_ESPI_PCR_LNKERR_SLV1                0x4054          ///< Link Error for Slave 1
+#define R_ESPI_PCR_CFG_VAL                    0xC00C          ///< ESPI Enabled Strap
+#define B_ESPI_PCR_CFG_VAL_ESPI_EN            BIT0            ///< ESPI Enabled Strap bit position
+#define R_ESPI_PCR_SOFTSTRAPS                 0xC210          ///< eSPI Sofstraps Register 0
+#define B_ESPI_PCR_SOFTSTRAPS_CS1_EN          BIT12           ///< CS1# Enable
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Register/PchRegsPsf.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Register/PchRegsPsf.h
new file mode 100644
index 0000000000..dc32f1e5b3
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Register/PchRegsPsf.h
@@ -0,0 +1,50 @@
+/** @file
+  Register definition for PSF component
+
+  Conventions:
+
+  - Register definition format:
+    Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpace_RegisterName
+  - Prefix:
+    Definitions beginning with "R_" are registers
+    Definitions beginning with "B_" are bits within registers
+    Definitions beginning with "V_" are meaningful values within the bits
+    Definitions beginning with "S_" are register size
+    Definitions beginning with "N_" are the bit position
+  - [GenerationName]:
+    Three letter acronym of the generation is used (e.g. SKL,KBL,CNL etc.).
+    Register name without GenerationName applies to all generations.
+  - [ComponentName]:
+    This field indicates the component name that the register belongs to (e.g. PCH, SA etc.)
+    Register name without ComponentName applies to all components.
+    Register that is specific to -LP denoted by "_PCH_LP_" in component name.
+  - SubsystemName:
+    This field indicates the subsystem name of the component that the register belongs to
+    (e.g. PCIE, USB, SATA, GPIO, PMC etc.).
+  - RegisterSpace:
+    MEM - MMIO space register of subsystem.
+    IO  - IO space register of subsystem.
+    PCR - Private configuration register of subsystem.
+    CFG - PCI configuration space register of subsystem.
+  - RegisterName:
+    Full register name.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_REGS_PSF_H_
+#define _PCH_REGS_PSF_H_
+//
+// PSFx segment registers
+//
+
+#define N_PCH_PSFX_PCR_MC_CONTROL_MCASTX_NUMMC          1
+#define B_PCH_PSFX_PCR_MC_CONTROL_MCASTX_MULTCEN        BIT0
+
+//
+// PSFx PCRs definitions
+//
+#define B_PCH_PSFX_PCR_TARGET_PSFID                     0xFF0000
+#define N_PCH_PSFX_PCR_TARGET_PSFID                     16
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Register/PchRegsPsth.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Register/PchRegsPsth.h
new file mode 100644
index 0000000000..2007eae44f
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Include/Register/PchRegsPsth.h
@@ -0,0 +1,66 @@
+/** @file
+  Register definition for PSTH component
+
+  Conventions:
+
+  - Register definition format:
+    Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpace_RegisterName
+  - Prefix:
+    Definitions beginning with "R_" are registers
+    Definitions beginning with "B_" are bits within registers
+    Definitions beginning with "V_" are meaningful values within the bits
+    Definitions beginning with "S_" are register size
+    Definitions beginning with "N_" are the bit position
+  - [GenerationName]:
+    Three letter acronym of the generation is used (e.g. SKL,KBL,CNL etc.).
+    Register name without GenerationName applies to all generations.
+  - [ComponentName]:
+    This field indicates the component name that the register belongs to (e.g. PCH, SA etc.)
+    Register name without ComponentName applies to all components.
+    Register that is specific to -LP denoted by "_PCH_LP_" in component name.
+  - SubsystemName:
+    This field indicates the subsystem name of the component that the register belongs to
+    (e.g. PCIE, USB, SATA, GPIO, PMC etc.).
+  - RegisterSpace:
+    MEM - MMIO space register of subsystem.
+    IO  - IO space register of subsystem.
+    PCR - Private configuration register of subsystem.
+    CFG - PCI configuration space register of subsystem.
+  - RegisterName:
+    Full register name.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_REGS_PSTH_H_
+#define _PCH_REGS_PSTH_H_
+
+//
+// Private chipset regsiter (Memory space) offset definition
+// The PCR register defines is used for PCR MMIO programming and PCH SBI programming as well.
+//
+
+//
+// PSTH and IO Trap PCRs (PID:PSTH)
+//
+#define R_PSTH_PCR_PSTHCTL          0x1D00                ///< PSTH control register
+#define B_PSTH_PCR_PSTHIOSFPTCGE    BIT2                  ///< PSTH IOSF primary trunk clock gating enable
+#define R_PSTH_PCR_TRPST            0x1E00                ///< Trap status regsiter
+#define R_PSTH_PCR_TRPC             0x1E10                ///< Trapped cycle
+#define B_PSTH_PCR_TRPC_RW          BIT24                 ///< Read/Write#: 1=Read, 0=Write
+#define B_PSTH_PCR_TRPC_AHBE        0x00000000000F0000    ///< Active high byte enables
+#define B_PSTH_PCR_TRPC_IOA         0x000000000000FFFC    ///< Trap cycle I/O address
+#define R_PSTH_PCR_TRPD             0x1E18                ///< Trapped write data
+#define R_PSTH_PCR_TRPREG0          0x1E80                ///< IO Tarp 0 register
+#define R_PSTH_PCR_TRPREG1          0x1E88                ///< IO Tarp 1 register
+#define R_PSTH_PCR_TRPREG2          0x1E90                ///< IO Tarp 2 register
+#define R_PSTH_PCR_TRPREG3          0x1E98                ///< IO Tarp 3 register
+#define B_PSTH_PCR_TRPREG_RWM       BIT17                 ///< 49 - 32 for 32 bit access, Read/Write mask
+#define B_PSTH_PCR_TRPREG_RWIO      BIT16                 ///< 48 - 32 for 32 bit access, Read/Write#, 1=Read, 0=Write
+#define N_PSTH_PCR_TRPREG_RWIO      16                    ///< 48 - 32 for 32 bit access, 16bit shift for Read/Write field
+#define N_PSTH_PCR_TRPREG_BEM       36
+#define N_PSTH_PCR_TRPREG_BE        32
+#define B_PSTH_PCR_TRPREG_AD        0x000000000000FFFC    ///< IO Address
+#define B_PSTH_PCR_TRPREG_TSE       BIT0                  ///< Trap and SMI# Enable
+
+#endif
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 06/40] TigerlakeSiliconPkg/Pch: Add IncludePrivate headers
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (3 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 05/40] TigerlakeSiliconPkg/Pch: Add include headers Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 07/40] TigerlakeSiliconPkg/SystemAgent: Add include headers Heng Luo
                   ` (33 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following header files:
  * Pch/IncludePrivate

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/Library/SiScheduleResetLib.h |  47 +++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/Library/SmmPchPrivateLib.h   |  26 ++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/PchConfigHob.h               | 269 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/PchHybridStorageHob.h        |  21 +++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/PchNvsAreaDef.h              | 319 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/PchRstHob.h                  |  58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/Protocol/PchNvsArea.h        |  30 ++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/Protocol/PcieIoTrap.h        |  35 +++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/SiScheduleResetHob.h         |  21 +++++++++++++++++++++
 9 files changed, 826 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/Library/SiScheduleResetLib.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/Library/SiScheduleResetLib.h
new file mode 100644
index 0000000000..2ad80a0269
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/Library/SiScheduleResetLib.h
@@ -0,0 +1,47 @@
+/** @file
+  Reset scheduling library services
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SI_SCHEDULE_RESET_LIB_H_
+#define _SI_SCHEDULE_RESET_LIB_H_
+
+#include <Uefi/UefiMultiPhase.h>
+#include <PchResetPlatformSpecific.h>
+
+/**
+  This function updates the reset information in SiScheduleResetHob
+  @param[in] ResetType        UEFI defined reset type.
+  @param[in] ResetData        Optional element used to introduce a platform specific reset.
+                               The exact type of the reset is defined by the EFI_GUID that follows
+                               the Null-terminated Unicode string.
+**/
+VOID
+SiScheduleResetSetType (
+  IN EFI_RESET_TYPE     ResetType,
+  IN PCH_RESET_DATA     *ResetData OPTIONAL
+  );
+
+/**
+  This function returns TRUE or FALSE depending on whether a reset is required based on SiScheduleResetHob
+
+  @retval     BOOLEAN       The function returns FALSE if no reset is required
+**/
+BOOLEAN
+SiScheduleResetIsRequired (
+  VOID
+  );
+
+/**
+  This function performs reset based on SiScheduleResetHob
+
+  @retval     BOOLEAN       The function returns FALSE if no reset is required
+**/
+BOOLEAN
+SiScheduleResetPerformReset (
+  VOID
+  );
+
+#endif //_SI_SCHEDULE_RESET_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/Library/SmmPchPrivateLib.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/Library/SmmPchPrivateLib.h
new file mode 100644
index 0000000000..955dac5a82
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/Library/SmmPchPrivateLib.h
@@ -0,0 +1,26 @@
+/** @file
+  Header file for private PCH SMM Lib.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SMM_PCH_PRIVATE_LIB_H_
+#define _SMM_PCH_PRIVATE_LIB_H_
+
+/**
+  Set InSmm.Sts bit
+**/
+VOID
+PchSetInSmmSts (
+  VOID
+  );
+
+/**
+  Clear InSmm.Sts bit
+**/
+VOID
+PchClearInSmmSts (
+  VOID
+  );
+
+#endif // _SMM_PCH_PRIVATE_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/PchConfigHob.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/PchConfigHob.h
new file mode 100644
index 0000000000..13a41f8d04
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/PchConfigHob.h
@@ -0,0 +1,269 @@
+/** @file
+  The GUID definition for PchConfigHob
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_CONFIG_HOB_H_
+#define _PCH_CONFIG_HOB_H_
+
+#include <ConfigBlock.h>
+#include <SmbusConfig.h>
+#include <InterruptConfig.h>
+#include <PchPcieRpConfig.h>
+#include <SataConfig.h>
+#include <RstConfig.h>
+#include <ConfigBlock/FlashProtectionConfig.h>
+#include <FivrConfig.h>
+#include <ThcConfig.h>
+#include <SerialIoConfig.h>
+
+
+extern EFI_GUID gPchConfigHobGuid;
+
+#pragma pack (push,1)
+
+/**
+  This structure contains the HOB which are related to PCH general config.
+**/
+typedef struct {
+  /**
+    This member describes whether or not the Compatibility Revision ID (CRID) feature
+    of PCH should be enabled. <b>0: Disable</b>; 1: Enable
+  **/
+  UINT32 Crid      :  1;
+  UINT32 RsvdBits0 : 31; ///< Reserved bits
+} GENERAL_HOB;
+
+/**
+  The SMBUS_CONFIG block lists the reserved addresses for non-ARP capable devices in the platform.
+**/
+typedef struct {
+  UINT8 RsvdBytes[3];          ///< Reserved bytes
+  UINT8 NumRsvdSmbusAddresses; ///< The number of elements in the RsvdSmbusAddressTable.
+  /**
+    Array of addresses reserved for non-ARP-capable SMBus devices.
+  **/
+  UINT8 RsvdSmbusAddressTable[PCH_MAX_SMBUS_RESERVED_ADDRESS];
+} SMBUS_HOB;
+
+/**
+  The INTERRUPT_HOB describes interrupt settings for PCH.
+**/
+typedef struct {
+  UINT8                        NumOfDevIntConfig;                             ///< Number of entries in DevIntConfig table
+  UINT8                        GpioIrqRoute;                                  ///< Interrupt routing for GPIO. Default is <b>14</b>.
+  UINT8                        Rsvd0[2];                                      ///< Reserved bytes, align to multiple 4.
+  PCH_DEVICE_INTERRUPT_CONFIG  DevIntConfig[PCH_MAX_DEVICE_INTERRUPT_CONFIG]; ///< Array which stores PCH devices interrupts settings
+} INTERRUPT_HOB;
+
+/**
+  The SERIAL_IO block provides the configurations to set the Serial IO controllers
+**/
+typedef struct {
+  SERIAL_IO_SPI_CONFIG  SpiDeviceConfig[PCH_MAX_SERIALIO_SPI_CONTROLLERS];   ///< SPI Configuration
+  SERIAL_IO_I2C_CONFIG  I2cDeviceConfig[PCH_MAX_SERIALIO_I2C_CONTROLLERS];   ///< I2C Configuration
+  SERIAL_IO_UART_CONFIG UartDeviceConfig[PCH_MAX_SERIALIO_UART_CONTROLLERS]; ///< UART Configuration
+} SERIAL_IO_HOB;
+
+/**
+  The PCIERP_HOB block describes the expected configuration of the PCH PCI Express controllers
+**/
+typedef struct {
+  ///
+  /// These members describe the configuration of each PCH PCIe root port.
+  ///
+  PCH_PCIE_ROOT_PORT_CONFIG    RootPort[PCH_MAX_PCIE_ROOT_PORTS];
+  PCH_PCIE_CLOCK               PcieClock[PCH_MAX_PCIE_CLOCKS];
+  /**
+    This member allows BIOS to control ICC PLL Shutdown by determining PCIe devices are LTR capable
+    or leaving untouched.
+    - <b>0: Disable, ICC PLL Shutdown is determined by PCIe device LTR capablility.</b>
+      - To allow ICC PLL shutdown if all present PCIe devices are LTR capable or if no PCIe devices are
+        presented for maximum power savings where possible.
+      - To disable ICC PLL shutdown when BIOS detects any non-LTR capable PCIe device for ensuring device
+        functionality.
+    - 1: Enable, To allow ICC PLL shutdown even if some devices do not support LTR capability.
+  **/
+  UINT32  AllowNoLtrIccPllShutdown :  1;
+  UINT32  RsvdBits0                : 31; ///< Reserved bits
+} PCIERP_HOB;
+
+/**
+  The HDAUDIO_HOB block describes the configuration of the PCH cAVS controller
+**/
+typedef struct {
+  UINT32  DspEnable             :  1; ///< DSP enablement: 0: Disable; <b>1: Enable</b>
+  UINT32  DspUaaCompliance      :  1; ///< UAA-mode Select: <b>0: Non-Uaa</b>; 1: UAA
+  UINT32  CodecSxWakeCapability :  1; ///< Capability to detect wake initiated by a codec in Sx, <b>0: Disable</b>; 1: Enable
+  UINT32  AudioLinkSndw1        :  1; ///< SoundWire1 link enablement: <b>0: Disable</b>; 1: Enable. Muxed with HDA
+  UINT32  AudioLinkSndw2        :  1; ///< SoundWire2 link enablement: <b>0: Disable</b>; 1: Enable. Muxed with SSP1
+  UINT32  AudioLinkSndw3        :  1; ///< SoundWire3 link enablement: <b>0: Disable</b>; 1: Enable. Muxed with DMIC1
+  UINT32  AudioLinkSndw4        :  1; ///< SoundWire4 link enablement: <b>0: Disable</b>; 1: Enable. Muxed with DMIC0
+  UINT32  Pme                   :  1; ///< Azalia wake-on-ring, <b>0: Disable</b>; 1: Enable
+  UINT32  RsvdBits0             : 24; ///< Reserved bits
+} HDAUDIO_HOB;
+
+/**
+  The SATA_HOB block describes the configuration of the PCH SATA controllers
+**/
+typedef struct {
+  /**
+    This member describes whether or not the SATA controllers should be enabled. 0: Disable; <b>1: Enable</b>.
+  **/
+  UINT32                        Enable          :  1;
+  UINT32                        TestMode        :  1; ///< <b>(Test)</b> <b>0: Disable</b>; 1: Allow entrance to the PCH SATA test modes
+  UINT32                        RsvdBits0       : 30; ///< Reserved bits
+  /**
+    This member configures the features, property, and capability for each SATA port.
+  **/
+  PCH_SATA_PORT_CONFIG          PortSettings[PCH_MAX_SATA_PORTS];
+} SATA_HOB;
+
+/**
+  The RST block describes the configuration of the RST PCIE Cycle Routers
+**/
+typedef struct {
+  /**
+    This member describes the details of implementation of Intel RST for PCIe Storage remapping (Intel RST Driver is required)
+  **/
+  RST_HARDWARE_REMAPPED_STORAGE_CONFIG   RstHardwareRemappedStorageConfig[PCH_MAX_RST_PCIE_STORAGE_CR];
+} RST_HOB;
+
+typedef struct {
+  UINT32  Enabled  : 1; ///< Indicates that SD card has been enabled
+  UINT32  Reserved : 31;
+} SD_CARD_HOB;
+
+/**
+  The EMMC_HOB block describes integrated eMMC settings for PCH.
+**/
+typedef struct {
+  UINT32  Enabled                      :  1;  ///< Determine if eMMC is enabled - 0: Disabled, <b>1: Enabled</b>.
+  UINT32  Hs400Enabled                 :  1;  ///< Determine eMMC HS400 Mode if EmmcEnabled - <b>0: Disabled</b>, 1: Enabled
+  /**
+    Determine if HS400 Training is required, set to FALSE if Hs400 Data is valid. <b>0: Disabled</b>, 1: Enabled.
+    First Boot or CMOS clear, system boot with Default settings, set tuning required.
+    Subsequent Boots, Get Variable 'Hs400TuningData'
+      - if failed to get variable, set tuning required
+      - if passed, retrieve Hs400DataValid, Hs400RxStrobe1Dll and Hs400TxDataDll from variable. Set tuning not required.
+  **/
+  UINT32  Hs400DllDataValid            :  1;  ///< Set if HS400 Tuning Data Valid
+  UINT32  RsvdBits                     : 29;
+} EMMC_HOB;
+
+/**
+  The PCH_LOCK_DOWN_CONFIG block describes the expected configuration of the PCH
+  for security requirement.
+**/
+typedef struct {
+  UINT32  GlobalSmi      :  1;
+  /**
+    <b>(Test)</b> Enable BIOS Interface Lock Down bit to prevent writes to the Backup Control Register
+    Top Swap bit and the General Control and Status Registers Boot BIOS Straps. 0: Disable; <b>1: Enable</b>.
+  **/
+  UINT32  BiosInterface  :  1;
+  /**
+    Enable the BIOS Lock Enable (BLE) feature and set EISS bit (D31:F5:RegDCh[5])
+    for the BIOS region protection. When it is enabled, the BIOS Region can only be
+    modified from SMM after EndOfDxe protocol is installed.
+    Note: When BiosLock is enabled, platform code also needs to update to take care
+    of BIOS modification (including SetVariable) in DXE or runtime phase after
+    EndOfDxe protocol is installed.
+    Enable InSMM.STS (EISS) in SPI
+    If this EISS bit is set, then WPD must be a '1' and InSMM.STS must be '1' also
+    in order to write to BIOS regions of SPI Flash. If this EISS bit is clear,
+    then the InSMM.STS is a don't care.
+    The BIOS must set the EISS bit while BIOS Guard support is enabled.
+    In recovery path, platform can temporary disable EISS for SPI programming in
+    PEI phase or early DXE phase.
+    0: Disable; <b>1: Enable.</b>
+  **/
+  UINT32  BiosLock        :  1;
+  UINT32  RsvdBits        : 29;
+} LOCK_DOWN_HOB;
+
+/**
+  The PM_HOB block describes expected miscellaneous power management settings.
+  The PowerResetStatusClear field would clear the Power/Reset status bits, please
+  set the bits if you want PCH Init driver to clear it, if you want to check the
+  status later then clear the bits.
+**/
+typedef struct {
+  UINT32 PsOnEnable             :  1; ///< Indicates if PS_ON support has been enabled, <b>0: Disable</b>; 1: Enable.
+  UINT32 EnableTimedGpio0       :  1; ///< Enable Bit for Timed GPIO 0 <b>0 = disable</b>; 1 = enable
+  UINT32 EnableTimedGpio1       :  1; ///< Enable Bit for Timed GPIO 1 <b>0 = disable</b>; 1 = enable
+  UINT32 RsvdBits1              : 29;
+} PM_HOB;
+
+/**
+  FIVR_HOB block
+**/
+typedef struct {
+  /**
+    Additional External Vnn VR rail configuration dedicated for Sx.
+    Required only if External Vnn VR needs different settings for Sx than
+    those specified in ExtVnnRail (refer to PCH_FIVR_CONFIG.ExtVnnRail)
+  **/
+  FIVR_EXT_RAIL_CONFIG     ExtVnnRailSx;
+} FIVR_HOB;
+
+/**
+  PCH Trace Hub HOB settings.
+**/
+typedef struct {
+  UINT32  PchTraceHubMode       :  2; ///< <b>0 = Disable</b>; 1 = Target Debugger mode; 2 = Host Debugger mode
+  UINT32  Rsvd1                 : 30; ///< Reserved bits
+  /**
+    Trace hub memory buffer region size policy.
+    The avaliable memory size options are: 0:0MB (none), 1:1MB, <b>2:8MB</b>, 3:64MB, 4:128MB, 5:256MB, 6:512MB.
+    Note : Limitation of total buffer size (CPU + PCH) is 512MB. If iTbt is enabled, the total size limits to 256 MB.
+    Refer to TRACE_BUFFER_SIZE
+  **/
+  UINT32  MemReg0Size;
+  UINT32  MemReg1Size;
+} PCH_TRACEHUB_HOB;
+
+/**
+  PCH eSPI HOB settings.
+**/
+typedef struct {
+  UINT32  BmeMasterSlaveEnabled :  1; ///< <b>0 = BME disable</b>; 1 = BME enable
+  UINT32  RsvdBits              : 31; ///< Reserved bits
+} PCH_ESPI_HOB;
+
+/**
+  THC HOB settings.
+**/
+typedef struct {
+  THC_PORT  ThcPort[2]; ///< Port Configuration
+} THC_HOB;
+
+
+/**
+  This structure contains the HOBs which are related to PCH controllers
+**/
+typedef struct {
+  EFI_HOB_GUID_TYPE  EfiHobGuidType;     ///< GUID HOB type structure for gPchConfigHobGuid
+  GENERAL_HOB        General;            ///< Pch general HOB definition
+  INTERRUPT_HOB      Interrupt;          ///< Interrupt HOB definition
+  SERIAL_IO_HOB      SerialIo;           ///< Serial io HOB definition
+  PCIERP_HOB         PcieRp;             ///< PCIE root port HOB definition
+  SD_CARD_HOB        SdCard;             ///< SD card HOB definition
+  EMMC_HOB           Emmc;               ///< eMMC HOB definition
+  LOCK_DOWN_HOB      LockDown;           ///< Lock down HOB definition
+  PM_HOB             Pm;                 ///< PM HOB definition
+  HDAUDIO_HOB        HdAudio;            ///< HD audio definition
+  SATA_HOB           Sata[PCH_MAX_SATA_CONTROLLERS]; ///< SATA definition
+  RST_HOB            Rst;                ///< RST definition
+  PROTECTED_RANGE    ProtectRange[PCH_FLASH_PROTECTED_RANGES];
+  SMBUS_HOB          Smbus;
+  PCH_TRACEHUB_HOB   PchTraceHub;        ///< PCH Trace Hub definition
+  PCH_ESPI_HOB       Espi;               ///< PCH eSPI definition
+  THC_HOB            Thc;                ///< PCH Tocuh Host Controller definition
+  FIVR_HOB           Fivr;               ///< PCH FIVR HOB definition
+
+
+} PCH_CONFIG_HOB;
+#pragma pack (pop)
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/PchHybridStorageHob.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/PchHybridStorageHob.h
new file mode 100644
index 0000000000..040bc270e6
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/PchHybridStorageHob.h
@@ -0,0 +1,21 @@
+/** @file
+
+  Definitions required to create HybridStorageHob
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_HYBRIDSTORAGE_HOB_
+#define _PCH_HYBRIDSTORAGE_HOB_
+
+extern EFI_GUID  gHybridStorageHobGuid;
+
+//
+//  Passes to DXE Hybrid Storage location
+//
+typedef struct {
+  UINT32 HybridStorageLocation;
+} PCH_HYBRIDSTORAGE_HOB;
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/PchNvsAreaDef.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/PchNvsAreaDef.h
new file mode 100644
index 0000000000..200f3ca8fa
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/PchNvsAreaDef.h
@@ -0,0 +1,319 @@
+//
+// Automatically generated by GenNvs ver 2.4.6
+// Please DO NOT modify !!!
+//
+
+/** @file
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+  //
+  // Define PCH NVS Area operatino region.
+  //
+#ifndef _PCH_NVS_AREA_DEF_H_
+#define _PCH_NVS_AREA_DEF_H_
+
+#pragma pack (push,1)
+typedef struct {
+  UINT16   PchSeries;                               ///< Offset 0       PCH Series
+  UINT16   PchGeneration;                           ///< Offset 2       PCH Generation
+  UINT16   PchStepping;                             ///< Offset 4       PCH Stepping
+  UINT32   RpAddress[28];                           ///< Offset 6       Root Port address 1
+                                                    ///< Offset 10      Root Port address 2
+                                                    ///< Offset 14      Root Port address 3
+                                                    ///< Offset 18      Root Port address 4
+                                                    ///< Offset 22      Root Port address 5
+                                                    ///< Offset 26      Root Port address 6
+                                                    ///< Offset 30      Root Port address 7
+                                                    ///< Offset 34      Root Port address 8
+                                                    ///< Offset 38      Root Port address 9
+                                                    ///< Offset 42      Root Port address 10
+                                                    ///< Offset 46      Root Port address 11
+                                                    ///< Offset 50      Root Port address 12
+                                                    ///< Offset 54      Root Port address 13
+                                                    ///< Offset 58      Root Port address 14
+                                                    ///< Offset 62      Root Port address 15
+                                                    ///< Offset 66      Root Port address 16
+                                                    ///< Offset 70      Root Port address 17
+                                                    ///< Offset 74      Root Port address 18
+                                                    ///< Offset 78      Root Port address 19
+                                                    ///< Offset 82      Root Port address 20
+                                                    ///< Offset 86      Root Port address 21
+                                                    ///< Offset 90      Root Port address 22
+                                                    ///< Offset 94      Root Port address 23
+                                                    ///< Offset 98      Root Port address 24
+                                                    ///< Offset 102     Root Port address 25
+                                                    ///< Offset 106     Root Port address 26
+                                                    ///< Offset 110     Root Port address 27
+                                                    ///< Offset 114     Root Port address 28
+  UINT64   NHLA;                                    ///< Offset 118     HD-Audio NHLT ACPI address
+  UINT32   NHLL;                                    ///< Offset 126     HD-Audio NHLT ACPI length
+  UINT32   ADFM;                                    ///< Offset 130     HD-Audio DSP Feature Mask
+  UINT8    SWQ0;                                    ///< Offset 134     HD-Audio SoundWire Link #1 quirk mask
+  UINT8    SWQ1;                                    ///< Offset 135     HD-Audio SoundWire Link #2 quirk mask
+  UINT8    SWQ2;                                    ///< Offset 136     HD-Audio SoundWire Link #3 quirk mask
+  UINT8    SWQ3;                                    ///< Offset 137     HD-Audio SoundWire Link #4 quirk mask
+  UINT8    ACS0;                                    ///< Offset 138     HD-Audio SoundWire Link #1 Autonomous Clock Stop
+  UINT8    ACS1;                                    ///< Offset 139     HD-Audio SoundWire Link #2 Autonomous Clock Stop
+  UINT8    ACS2;                                    ///< Offset 140     HD-Audio SoundWire Link #3 Autonomous Clock Stop
+  UINT8    ACS3;                                    ///< Offset 141     HD-Audio SoundWire Link #4 Autonomous Clock Stop
+  UINT8    DAI0;                                    ///< Offset 142     HD-Audio SoundWire Link #1 Data On Active Interval Select
+  UINT8    DAI1;                                    ///< Offset 143     HD-Audio SoundWire Link #2 Data On Active Interval Select
+  UINT8    DAI2;                                    ///< Offset 144     HD-Audio SoundWire Link #3 Data On Active Interval Select
+  UINT8    DAI3;                                    ///< Offset 145     HD-Audio SoundWire Link #4 Data On Active Interval Select
+  UINT8    DOD0;                                    ///< Offset 146     HD-Audio SoundWire Link #1 Data On Delay Select
+  UINT8    DOD1;                                    ///< Offset 147     HD-Audio SoundWire Link #2 Data On Delay Select
+  UINT8    DOD2;                                    ///< Offset 148     HD-Audio SoundWire Link #3 Data On Delay Select
+  UINT8    DOD3;                                    ///< Offset 149     HD-Audio SoundWire Link #4 Data On Delay Select
+  UINT8    SWMC;                                    ///< Offset 150     HD-Audio SoundWire Master Count
+  UINT8    XTAL;                                    ///< Offset 151     XTAL frequency: 0: 24MHz; 1: 38.4MHz; 2: Unsupported
+  UINT32   DSPM;                                    ///< Offset 152     HD-Audio DSP Stolen Memory Base Address (@todo: Remove after CNL-LP B0)
+  UINT32   SBRG;                                    ///< Offset 156     SBREG_BAR
+  UINT8    GEI0;                                    ///< Offset 160     GPIO GroupIndex mapped to GPE_DW0
+  UINT8    GEI1;                                    ///< Offset 161     GPIO GroupIndex mapped to GPE_DW1
+  UINT8    GEI2;                                    ///< Offset 162     GPIO GroupIndex mapped to GPE_DW2
+  UINT8    GED0;                                    ///< Offset 163     GPIO DW part of group mapped to GPE_DW0
+  UINT8    GED1;                                    ///< Offset 164     GPIO DW part of group mapped to GPE_DW1
+  UINT8    GED2;                                    ///< Offset 165     GPIO DW part of group mapped to GPE_DW2
+  UINT16   PcieLtrMaxSnoopLatency[28];              ///< Offset 166     PCIE LTR max snoop Latency 1
+                                                    ///< Offset 168     PCIE LTR max snoop Latency 2
+                                                    ///< Offset 170     PCIE LTR max snoop Latency 3
+                                                    ///< Offset 172     PCIE LTR max snoop Latency 4
+                                                    ///< Offset 174     PCIE LTR max snoop Latency 5
+                                                    ///< Offset 176     PCIE LTR max snoop Latency 6
+                                                    ///< Offset 178     PCIE LTR max snoop Latency 7
+                                                    ///< Offset 180     PCIE LTR max snoop Latency 8
+                                                    ///< Offset 182     PCIE LTR max snoop Latency 9
+                                                    ///< Offset 184     PCIE LTR max snoop Latency 10
+                                                    ///< Offset 186     PCIE LTR max snoop Latency 11
+                                                    ///< Offset 188     PCIE LTR max snoop Latency 12
+                                                    ///< Offset 190     PCIE LTR max snoop Latency 13
+                                                    ///< Offset 192     PCIE LTR max snoop Latency 14
+                                                    ///< Offset 194     PCIE LTR max snoop Latency 15
+                                                    ///< Offset 196     PCIE LTR max snoop Latency 16
+                                                    ///< Offset 198     PCIE LTR max snoop Latency 17
+                                                    ///< Offset 200     PCIE LTR max snoop Latency 18
+                                                    ///< Offset 202     PCIE LTR max snoop Latency 19
+                                                    ///< Offset 204     PCIE LTR max snoop Latency 20
+                                                    ///< Offset 206     PCIE LTR max snoop Latency 21
+                                                    ///< Offset 208     PCIE LTR max snoop Latency 22
+                                                    ///< Offset 210     PCIE LTR max snoop Latency 23
+                                                    ///< Offset 212     PCIE LTR max snoop Latency 24
+                                                    ///< Offset 214     PCIE LTR max snoop Latency 25
+                                                    ///< Offset 216     PCIE LTR max snoop Latency 26
+                                                    ///< Offset 218     PCIE LTR max snoop Latency 27
+                                                    ///< Offset 220     PCIE LTR max snoop Latency 28
+  UINT16   PcieLtrMaxNoSnoopLatency[28];            ///< Offset 222     PCIE LTR max no snoop Latency 1
+                                                    ///< Offset 224     PCIE LTR max no snoop Latency 2
+                                                    ///< Offset 226     PCIE LTR max no snoop Latency 3
+                                                    ///< Offset 228     PCIE LTR max no snoop Latency 4
+                                                    ///< Offset 230     PCIE LTR max no snoop Latency 5
+                                                    ///< Offset 232     PCIE LTR max no snoop Latency 6
+                                                    ///< Offset 234     PCIE LTR max no snoop Latency 7
+                                                    ///< Offset 236     PCIE LTR max no snoop Latency 8
+                                                    ///< Offset 238     PCIE LTR max no snoop Latency 9
+                                                    ///< Offset 240     PCIE LTR max no snoop Latency 10
+                                                    ///< Offset 242     PCIE LTR max no snoop Latency 11
+                                                    ///< Offset 244     PCIE LTR max no snoop Latency 12
+                                                    ///< Offset 246     PCIE LTR max no snoop Latency 13
+                                                    ///< Offset 248     PCIE LTR max no snoop Latency 14
+                                                    ///< Offset 250     PCIE LTR max no snoop Latency 15
+                                                    ///< Offset 252     PCIE LTR max no snoop Latency 16
+                                                    ///< Offset 254     PCIE LTR max no snoop Latency 17
+                                                    ///< Offset 256     PCIE LTR max no snoop Latency 18
+                                                    ///< Offset 258     PCIE LTR max no snoop Latency 19
+                                                    ///< Offset 260     PCIE LTR max no snoop Latency 20
+                                                    ///< Offset 262     PCIE LTR max no snoop Latency 21
+                                                    ///< Offset 264     PCIE LTR max no snoop Latency 22
+                                                    ///< Offset 266     PCIE LTR max no snoop Latency 23
+                                                    ///< Offset 268     PCIE LTR max no snoop Latency 24
+                                                    ///< Offset 270     PCIE LTR max no snoop Latency 25
+                                                    ///< Offset 272     PCIE LTR max no snoop Latency 26
+                                                    ///< Offset 274     PCIE LTR max no snoop Latency 27
+                                                    ///< Offset 276     PCIE LTR max no snoop Latency 28
+  UINT8    XHPC;                                    ///< Offset 278     Number of HighSpeed ports implemented in XHCI controller
+  UINT8    XRPC;                                    ///< Offset 279     Number of USBR ports implemented in XHCI controller
+  UINT8    XSPC;                                    ///< Offset 280     Number of SuperSpeed ports implemented in XHCI controller
+  UINT8    XSPA;                                    ///< Offset 281     Address of 1st SuperSpeed port
+  UINT32   HPTB;                                    ///< Offset 282     HPET base address
+  UINT8    HPTE;                                    ///< Offset 286     HPET enable
+  //SerialIo block
+  UINT8    SM0[7];                                  ///< Offset 287     SerialIo SPI Controller 0 Mode
+                                                    ///< Offset 288     SerialIo SPI Controller 1 Mode
+                                                    ///< Offset 289     SerialIo SPI Controller 2 Mode
+                                                    ///< Offset 290     SerialIo SPI Controller 3 Mode
+                                                    ///< Offset 291     SerialIo SPI Controller 4 Mode
+                                                    ///< Offset 292     SerialIo SPI Controller 5 Mode
+                                                    ///< Offset 293     SerialIo SPI Controller 6 Mode
+  UINT64   SC0[7];                                  ///< Offset 294     SerialIo SPI Controller 0 Pci Config
+                                                    ///< Offset 302     SerialIo SPI Controller 1 Pci Config
+                                                    ///< Offset 310     SerialIo SPI Controller 2 Pci Config
+                                                    ///< Offset 318     SerialIo SPI Controller 3 Pci Config
+                                                    ///< Offset 326     SerialIo SPI Controller 4 Pci Config
+                                                    ///< Offset 334     SerialIo SPI Controller 5 Pci Config
+                                                    ///< Offset 342     SerialIo SPI Controller 6 Pci Config
+  UINT8    IM0[8];                                  ///< Offset 350     SerialIo I2C Controller 0 Mode
+                                                    ///< Offset 351     SerialIo I2C Controller 1 Mode
+                                                    ///< Offset 352     SerialIo I2C Controller 2 Mode
+                                                    ///< Offset 353     SerialIo I2C Controller 3 Mode
+                                                    ///< Offset 354     SerialIo I2C Controller 4 Mode
+                                                    ///< Offset 355     SerialIo I2C Controller 5 Mode
+                                                    ///< Offset 356     SerialIo I2C Controller 6 Mode
+                                                    ///< Offset 357     SerialIo I2C Controller 7 Mode
+  UINT64   IC0[8];                                  ///< Offset 358     SerialIo I2C Controller 0 Pci Config
+                                                    ///< Offset 366     SerialIo I2C Controller 1 Pci Config
+                                                    ///< Offset 374     SerialIo I2C Controller 2 Pci Config
+                                                    ///< Offset 382     SerialIo I2C Controller 3 Pci Config
+                                                    ///< Offset 390     SerialIo I2C Controller 4 Pci Config
+                                                    ///< Offset 398     SerialIo I2C Controller 5 Pci Config
+                                                    ///< Offset 406     SerialIo I2C Controller 6 Pci Config
+                                                    ///< Offset 414     SerialIo I2C Controller 7 Pci Config
+  UINT8    UM0[7];                                  ///< Offset 422     SerialIo UART Controller 0 Mode
+                                                    ///< Offset 423     SerialIo UART Controller 1 Mode
+                                                    ///< Offset 424     SerialIo UART Controller 2 Mode
+                                                    ///< Offset 425     SerialIo UART Controller 3 Mode
+                                                    ///< Offset 426     SerialIo UART Controller 4 Mode
+                                                    ///< Offset 427     SerialIo UART Controller 5 Mode
+                                                    ///< Offset 428     SerialIo UART Controller 6 Mode
+  UINT64   UC0[7];                                  ///< Offset 429     SerialIo UART Controller 0 Pci Config
+                                                    ///< Offset 437     SerialIo UART Controller 1 Pci Config
+                                                    ///< Offset 445     SerialIo UART Controller 2 Pci Config
+                                                    ///< Offset 453     SerialIo UART Controller 3 Pci Config
+                                                    ///< Offset 461     SerialIo UART Controller 4 Pci Config
+                                                    ///< Offset 469     SerialIo UART Controller 5 Pci Config
+                                                    ///< Offset 477     SerialIo UART Controller 6 Pci Config
+  UINT8    UD0[7];                                  ///< Offset 485     SerialIo UART Controller 0 DmaEnable
+                                                    ///< Offset 486     SerialIo UART Controller 1 DmaEnable
+                                                    ///< Offset 487     SerialIo UART Controller 2 DmaEnable
+                                                    ///< Offset 488     SerialIo UART Controller 3 DmaEnable
+                                                    ///< Offset 489     SerialIo UART Controller 4 DmaEnable
+                                                    ///< Offset 490     SerialIo UART Controller 5 DmaEnable
+                                                    ///< Offset 491     SerialIo UART Controller 6 DmaEnable
+  UINT8    UP0[7];                                  ///< Offset 492     SerialIo UART Controller 0 Power Gating
+                                                    ///< Offset 493     SerialIo UART Controller 1 Power Gating
+                                                    ///< Offset 494     SerialIo UART Controller 2 Power Gating
+                                                    ///< Offset 495     SerialIo UART Controller 3 Power Gating
+                                                    ///< Offset 496     SerialIo UART Controller 4 Power Gating
+                                                    ///< Offset 497     SerialIo UART Controller 5 Power Gating
+                                                    ///< Offset 498     SerialIo UART Controller 6 Power Gating
+  UINT8    UI0[7];                                  ///< Offset 499     SerialIo UART Controller 0 Irq
+                                                    ///< Offset 500     SerialIo UART Controller 1 Irq
+                                                    ///< Offset 501     SerialIo UART Controller 2 Irq
+                                                    ///< Offset 502     SerialIo UART Controller 3 Irq
+                                                    ///< Offset 503     SerialIo UART Controller 4 Irq
+                                                    ///< Offset 504     SerialIo UART Controller 5 Irq
+                                                    ///< Offset 505     SerialIo UART Controller 6 Irq
+  //end of SerialIo block
+  UINT8    SGIR;                                    ///< Offset 506     GPIO IRQ
+  UINT8    GPHD;                                    ///< Offset 507     Hide GPIO ACPI device
+  UINT8    RstPcieStorageInterfaceType[3];          ///< Offset 508     RST PCIe Storage Cycle Router#1 Interface Type
+                                                    ///< Offset 509     RST PCIe Storage Cycle Router#2 Interface Type
+                                                    ///< Offset 510     RST PCIe Storage Cycle Router#3 Interface Type
+  UINT8    RstPcieStoragePmCapPtr[3];               ///< Offset 511     RST PCIe Storage Cycle Router#1 Power Management Capability Pointer
+                                                    ///< Offset 512     RST PCIe Storage Cycle Router#2 Power Management Capability Pointer
+                                                    ///< Offset 513     RST PCIe Storage Cycle Router#3 Power Management Capability Pointer
+  UINT8    RstPcieStoragePcieCapPtr[3];             ///< Offset 514     RST PCIe Storage Cycle Router#1 PCIe Capabilities Pointer
+                                                    ///< Offset 515     RST PCIe Storage Cycle Router#2 PCIe Capabilities Pointer
+                                                    ///< Offset 516     RST PCIe Storage Cycle Router#3 PCIe Capabilities Pointer
+  UINT16   RstPcieStorageL1ssCapPtr[3];             ///< Offset 517     RST PCIe Storage Cycle Router#1 L1SS Capability Pointer
+                                                    ///< Offset 519     RST PCIe Storage Cycle Router#2 L1SS Capability Pointer
+                                                    ///< Offset 521     RST PCIe Storage Cycle Router#3 L1SS Capability Pointer
+  UINT8    RstPcieStorageEpL1ssControl2[3];         ///< Offset 523     RST PCIe Storage Cycle Router#1 Endpoint L1SS Control Data2
+                                                    ///< Offset 524     RST PCIe Storage Cycle Router#2 Endpoint L1SS Control Data2
+                                                    ///< Offset 525     RST PCIe Storage Cycle Router#3 Endpoint L1SS Control Data2
+  UINT32   RstPcieStorageEpL1ssControl1[3];         ///< Offset 526     RST PCIe Storage Cycle Router#1 Endpoint L1SS Control Data1
+                                                    ///< Offset 530     RST PCIe Storage Cycle Router#2 Endpoint L1SS Control Data1
+                                                    ///< Offset 534     RST PCIe Storage Cycle Router#3 Endpoint L1SS Control Data1
+  UINT16   RstPcieStorageLtrCapPtr[3];              ///< Offset 538     RST PCIe Storage Cycle Router#1 LTR Capability Pointer
+                                                    ///< Offset 540     RST PCIe Storage Cycle Router#2 LTR Capability Pointer
+                                                    ///< Offset 542     RST PCIe Storage Cycle Router#3 LTR Capability Pointer
+  UINT32   RstPcieStorageEpLtrData[3];              ///< Offset 544     RST PCIe Storage Cycle Router#1 Endpoint LTR Data
+                                                    ///< Offset 548     RST PCIe Storage Cycle Router#2 Endpoint LTR Data
+                                                    ///< Offset 552     RST PCIe Storage Cycle Router#3 Endpoint LTR Data
+  UINT16   RstPcieStorageEpLctlData16[3];           ///< Offset 556     RST PCIe Storage Cycle Router#1 Endpoint LCTL Data
+                                                    ///< Offset 558     RST PCIe Storage Cycle Router#2 Endpoint LCTL Data
+                                                    ///< Offset 560     RST PCIe Storage Cycle Router#3 Endpoint LCTL Data
+  UINT16   RstPcieStorageEpDctlData16[3];           ///< Offset 562     RST PCIe Storage Cycle Router#1 Endpoint DCTL Data
+                                                    ///< Offset 564     RST PCIe Storage Cycle Router#2 Endpoint DCTL Data
+                                                    ///< Offset 566     RST PCIe Storage Cycle Router#3 Endpoint DCTL Data
+  UINT16   RstPcieStorageEpDctl2Data16[3];          ///< Offset 568     RST PCIe Storage Cycle Router#1 Endpoint DCTL2 Data
+                                                    ///< Offset 570     RST PCIe Storage Cycle Router#2 Endpoint DCTL2 Data
+                                                    ///< Offset 572     RST PCIe Storage Cycle Router#3 Endpoint DCTL2 Data
+  UINT16   RstPcieStorageRpDctl2Data16[3];          ///< Offset 574     RST PCIe Storage Cycle Router#1 RootPort DCTL2 Data
+                                                    ///< Offset 576     RST PCIe Storage Cycle Router#2 RootPort DCTL2 Data
+                                                    ///< Offset 578     RST PCIe Storage Cycle Router#3 RootPort DCTL2 Data
+  UINT32   RstPcieStorageUniqueTableBar[3];         ///< Offset 580     RST PCIe Storage Cycle Router#1 Endpoint unique MSI-X Table BAR
+                                                    ///< Offset 584     RST PCIe Storage Cycle Router#2 Endpoint unique MSI-X Table BAR
+                                                    ///< Offset 588     RST PCIe Storage Cycle Router#3 Endpoint unique MSI-X Table BAR
+  UINT32   RstPcieStorageUniqueTableBarValue[3];    ///< Offset 592     RST PCIe Storage Cycle Router#1 Endpoint unique MSI-X Table BAR value
+                                                    ///< Offset 596     RST PCIe Storage Cycle Router#2 Endpoint unique MSI-X Table BAR value
+                                                    ///< Offset 600     RST PCIe Storage Cycle Router#3 Endpoint unique MSI-X Table BAR value
+  UINT32   RstPcieStorageUniquePbaBar[3];           ///< Offset 604     RST PCIe Storage Cycle Router#1 Endpoint unique MSI-X PBA BAR
+                                                    ///< Offset 608     RST PCIe Storage Cycle Router#2 Endpoint unique MSI-X PBA BAR
+                                                    ///< Offset 612     RST PCIe Storage Cycle Router#3 Endpoint unique MSI-X PBA BAR
+  UINT32   RstPcieStorageUniquePbaBarValue[3];      ///< Offset 616     RST PCIe Storage Cycle Router#1 Endpoint unique MSI-X PBA BAR value
+                                                    ///< Offset 620     RST PCIe Storage Cycle Router#2 Endpoint unique MSI-X PBA BAR value
+                                                    ///< Offset 624     RST PCIe Storage Cycle Router#3 Endpoint unique MSI-X PBA BAR value
+  UINT32   RstPcieStorageRootPortNum[3];            ///< Offset 628     RST PCIe Storage Cycle Router#1 Root Port number
+                                                    ///< Offset 632     RST PCIe Storage Cycle Router#2 Root Port number
+                                                    ///< Offset 636     RST PCIe Storage Cycle Router#3 Root Port number
+  UINT8    EMH4;                                    ///< Offset 640     eMMC HS400 mode enabled
+  UINT8    EMDS;                                    ///< Offset 641     eMMC Driver Strength
+  UINT8    CpuSku;                                  ///< Offset 642     CPU SKU
+  UINT16   IoTrapAddress[4];                        ///< Offset 643
+  UINT8    IoTrapStatus[4];                         ///< Offset 651
+  UINT16   PMBS;                                    ///< Offset 655     ACPI IO BASE address
+  UINT32   PWRM;                                    ///< Offset 657     PWRM MEM BASE address
+  // CNVi specific
+  UINT8    CnviMode;                                ///< Offset 661     CNVi mode
+  UINT8    CnviBtCore;                              ///< Offset 662     CNVi BT Core
+  UINT8    CnviBtAudioOffload;                      ///< Offset 663     CNVi BT Audio Offload
+  // PCH Trace Hub
+  UINT8    PchTraceHubMode;                         ///< Offset 664     PCH Trace Hub Mode
+  // PCH PS_ON support
+  UINT8    PsOnEnable;                              ///< Offset 665     PCH PS_ON enable
+  //
+  // These are for PchApciTablesSelfTest use
+  //
+  UINT8    LtrEnable[24];                           ///< Offset 666     Latency Tolerance Reporting Enable
+                                                    ///< Offset 667     Latency Tolerance Reporting Enable
+                                                    ///< Offset 668     Latency Tolerance Reporting Enable
+                                                    ///< Offset 669     Latency Tolerance Reporting Enable
+                                                    ///< Offset 670     Latency Tolerance Reporting Enable
+                                                    ///< Offset 671     Latency Tolerance Reporting Enable
+                                                    ///< Offset 672     Latency Tolerance Reporting Enable
+                                                    ///< Offset 673     Latency Tolerance Reporting Enable
+                                                    ///< Offset 674     Latency Tolerance Reporting Enable
+                                                    ///< Offset 675     Latency Tolerance Reporting Enable
+                                                    ///< Offset 676     Latency Tolerance Reporting Enable
+                                                    ///< Offset 677     Latency Tolerance Reporting Enable
+                                                    ///< Offset 678     Latency Tolerance Reporting Enable
+                                                    ///< Offset 679     Latency Tolerance Reporting Enable
+                                                    ///< Offset 680     Latency Tolerance Reporting Enable
+                                                    ///< Offset 681     Latency Tolerance Reporting Enable
+                                                    ///< Offset 682     Latency Tolerance Reporting Enable
+                                                    ///< Offset 683     Latency Tolerance Reporting Enable
+                                                    ///< Offset 684     Latency Tolerance Reporting Enable
+                                                    ///< Offset 685     Latency Tolerance Reporting Enable
+                                                    ///< Offset 686     Latency Tolerance Reporting Enable
+                                                    ///< Offset 687     Latency Tolerance Reporting Enable
+                                                    ///< Offset 688     Latency Tolerance Reporting Enable
+                                                    ///< Offset 689     Latency Tolerance Reporting Enable
+  UINT8    GBES;                                    ///< Offset 690     GbE Support
+  UINT32   PchxDCIPwrDnScale;                       ///< Offset 691     PCH xDCI Power Down Scale Value, DWC_USB3_GCTL_INIT[31:19]
+  UINT8    EmmcEnabled;                             ///< Offset 695     Set to indicate that eMMC is enabled
+  UINT8    SdCardEnabled;                           ///< Offset 696     Set to indicate that SD card is enabled
+  UINT8    EnableTimedGpio0;                        ///< Offset 697     Set to indicate that Timed GPIO 0 is enabled
+  UINT8    EnableTimedGpio1;                        ///< Offset 698     Set to indicate that Timed GPIO 1 is enabled
+  UINT8    ClockToRootPortMap[18];                  ///< Offset 699     CLOCK index to root port index map. Used during PCIe D3Cold flows
+  UINT16   TcoBase;                                 ///< Offset 717     TCO base address
+  UINT16   IclkPid;                                 ///< Offset 719     Iclk PID number
+  UINT16   CnviPortId;                              ///< Offset 721     CNVi sideband port id
+  UINT32   HybridStorageLocation;                   ///< Offset 723
+  UINT8    SataPortPresence;                        ///< Offset 727     Holds information from SATA PCS register about SATA ports which recieved COMINIT from connected devices.
+} PCH_NVS_AREA;
+
+#pragma pack(pop)
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/PchRstHob.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/PchRstHob.h
new file mode 100644
index 0000000000..428858afcf
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/PchRstHob.h
@@ -0,0 +1,58 @@
+/** @file
+
+  Definitions required to create RstHob
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_RST_HOB_
+#define _PCH_RST_HOB_
+
+extern EFI_GUID  gPchRstHobGuid;
+
+//
+// This struct is used to record the fields that should be restored during device wake up
+//
+typedef struct {
+  UINT8     PmCapPtr;
+  UINT8     PcieCapPtr;
+  UINT16    L1ssCapPtr;
+  UINT8     EndpointL1ssControl2;
+  UINT32    EndpointL1ssControl1;
+  UINT16    LtrCapPtr;
+  UINT32    EndpointLtrData;
+  UINT16    EndpointLctlData16;
+  UINT16    EndpointDctlData16;
+  UINT16    EndpointDctl2Data16;
+  UINT16    RootPortDctl2Data16;
+} SAVED_DEVICE_CONFIG_SPACE;
+
+//
+// This structure is used to record the result of PCIe storageremapping for each cycle router
+//
+typedef struct {
+  UINT8                                 RootPortNum;                      // Indicates the root port number with RST PCIe Storage Remapping remapping supported and PCIe storage device plugged on, numbering is 0-based
+  UINT8                                 DeviceInterface;                  // Indicates the interface of the PCIe storage device (AHCI or NVMe)
+  UINT32                                EndPointUniqueMsixTableBar;       // Records the PCIe storage device's MSI-X Table BAR if it supports unique MSI-X Table BAR
+  UINT32                                EndPointUniqueMsixTableBarValue;  // Records the PCIe storage device's MSI-X Table BAR value if it supports unique MSI-X Table BAR
+  UINT32                                EndPointUniqueMsixPbaBar;         // Records the PCIe storage device's MSI-X PBA BAR if it supports unique MSI-X PBA BAR
+  UINT32                                EndPointUniqueMsixPbaBarValue;    // Records the PCIe storage device's MSI-X PBA BAR value if it supports unique MSI-X PBA BAR
+} RST_CR_CONFIGURATION;
+
+//
+//  Passes to DXE results of PCIe storage remapping
+//
+typedef struct {
+  //
+  // Stores configuration information about cycle router
+  //
+  RST_CR_CONFIGURATION  RstCrConfiguration[PCH_MAX_RST_PCIE_STORAGE_CR];
+
+  //
+  // Saved fields from hidden device config space to be used later by RST driver
+  //
+  SAVED_DEVICE_CONFIG_SPACE  SavedRemapedDeviceConfigSpace[PCH_MAX_RST_PCIE_STORAGE_CR];
+} PCH_RST_HOB;
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/Protocol/PchNvsArea.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/Protocol/PchNvsArea.h
new file mode 100644
index 0000000000..1c45d89225
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/Protocol/PchNvsArea.h
@@ -0,0 +1,30 @@
+/** @file
+  This file defines the PCH NVS Area Protocol.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_NVS_AREA_H_
+#define _PCH_NVS_AREA_H_
+
+//
+// PCH NVS Area definition
+//
+#include <Pch/IncludePrivate/PchNvsAreaDef.h>
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID                         gPchNvsAreaProtocolGuid;
+
+/**
+  This protocol is used to sync PCH information from POST to runtime ASL.
+  This protocol exposes the pointer of PCH NVS Area only. Please refer to
+  ASL definition for PCH NVS AREA.
+**/
+typedef struct {
+  PCH_NVS_AREA                          *Area;
+} PCH_NVS_AREA_PROTOCOL;
+
+#endif // _PCH_NVS_AREA_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/Protocol/PcieIoTrap.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/Protocol/PcieIoTrap.h
new file mode 100644
index 0000000000..ecea5db4fc
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/Protocol/PcieIoTrap.h
@@ -0,0 +1,35 @@
+/** @file
+  This file defines the PCH PCIE IoTrap Protocol.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_PCIE_IOTRAP_H_
+#define _PCH_PCIE_IOTRAP_H_
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID                       gPchPcieIoTrapProtocolGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _PCH_PCIE_IOTRAP_PROTOCOL PCH_PCIE_IOTRAP_PROTOCOL;
+
+///
+/// Pcie Trap valid types
+///
+typedef enum {
+  PchPciePmTrap,
+  PcieTrapTypeMaximum
+} PCH_PCIE_TRAP_TYPE;
+
+/**
+ This protocol is used to provide the IoTrap address to trigger PCH PCIE call back events
+**/
+struct _PCH_PCIE_IOTRAP_PROTOCOL {
+  UINT16      PcieTrapAddress;
+};
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/SiScheduleResetHob.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/SiScheduleResetHob.h
new file mode 100644
index 0000000000..0d9b167588
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/IncludePrivate/SiScheduleResetHob.h
@@ -0,0 +1,21 @@
+/** @file
+  This file contains definitions of Si Schedule Reset HOB.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SI_SCHEDULE_RESET_HOB_H_
+#define _SI_SCHEDULE_RESET_HOB_H_
+
+/**
+  This structure is used to provide information about PCH Resets
+**/
+typedef struct {
+  EFI_RESET_TYPE             ResetType;
+  PCH_RESET_DATA             ResetData;
+} SI_SCHEDULE_RESET_HOB;
+
+extern EFI_GUID gSiScheduleResetHobGuid;
+
+#endif // _SI_SCHEDULE_RESET_HOB_H_
+
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 07/40] TigerlakeSiliconPkg/SystemAgent: Add include headers
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (4 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 06/40] TigerlakeSiliconPkg/Pch: Add IncludePrivate headers Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 08/40] TigerlakeSiliconPkg/SystemAgent: Add IncludePrivate headers Heng Luo
                   ` (32 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following header files:
  * SystemAgent/Include

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryDxeConfig.h       | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieDxeConfig.h         | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/ConfigBlock/PramPreMemConfig.h      |  34 ++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiConfig.h       |  24 ++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiPreMemConfig.h | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/Library/SaPlatformLib.h             |  48 ++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/MemInfoHob.h                        | 245 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/Protocol/SaPolicy.h                 |  61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 753 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryDxeConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryDxeConfig.h
new file mode 100644
index 0000000000..451e295b49
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/ConfigBlock/MemoryDxeConfig.h
@@ -0,0 +1,123 @@
+/** @file
+  Memory DXE Policy definitions
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _MEMORY_DXE_CONFIG_H_
+#define _MEMORY_DXE_CONFIG_H_
+
+#pragma pack(push, 1)
+
+#define MEMORY_DXE_CONFIG_REVISION 1
+
+typedef struct _MEMORY_DXE_CONFIG  MEMORY_DXE_CONFIG;
+
+/**
+  Retrieves the OEM custom string for the SMBIOS Type 17 Table DeviceLocator field.
+  Implementation of this function is optional, if this function pointer is NULL then
+  the reference implementation of DeviceLocator will be used.
+
+  @param[in]  This                          A pointer to this instance of MEMORY_DXE_CONFIG.
+  @param[in]  Controller                    Desired Controller to get a DeviceLocator string for.
+  @param[in]  Dimm                          Desired DIMM to get a DeviceLocator string for.
+  @param[in]  MdSocket                      0 = Memory Down, 1 = Socketed.
+
+  @retval                                   The DeviceLocator string
+  @retval     NULL                          If the return value is NULL, the default value will be used.
+**/
+typedef
+CHAR8*
+(EFIAPI *MEMORY_DXE_CONFIG_GET_DEVICE_LOCATOR_STRING)(
+  IN CONST    MEMORY_DXE_CONFIG   *This,
+  IN          UINT8               Controller,
+  IN          UINT8               Dimm,
+  IN          UINT8               MdSocket
+  );
+
+/**
+  Retrieves the OEM custom string for the SMBIOS Type 17 Table BankLocator field.
+  Implementation of this function is optional, if this function pointer is NULL then
+  the reference implementation of DeviceLocator will be used.
+
+  @param[in]  This                          A pointer to this instance of MEMORY_DXE_CONFIG.
+  @param[in]  Controller                    Desired Controller to get a BankLocator string for.
+  @param[in]  Dimm                          Desired DIMM to get a BankLocator string for.
+  @param[in]  MdSocket                      0 = Memory Down, 1 = Socketed.
+
+  @retval                                   The BankLocator string
+  @retval     NULL                          If the return value is NULL, the default value will be used.
+**/
+typedef
+CHAR8*
+(EFIAPI *MEMORY_DXE_CONFIG_GET_BANK_LOCATOR_STRING)(
+  IN CONST    MEMORY_DXE_CONFIG   *This,
+  IN          UINT8               Controller,
+  IN          UINT8               Dimm,
+  IN          UINT8               MdSocket
+  );
+
+/**
+  The Memory Configuration includes DIMM SPD address Map and DIMM Slot Mechanical present bit map.
+  The data elements should be initialized by a Platform Module.\n
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+struct _MEMORY_DXE_CONFIG {
+  CONFIG_BLOCK_HEADER   Header;                   ///< Offset 0-27: Config Block Header
+/**
+  Offset 28:
+  Dimm SPD address
+  Only Server support 2 channels * 3 slots per channel = 6 sockets totally
+  The Desktop and mobile only support 2 channels * 2 slots per channel = 4 sockets totally
+  So there is mapping rule here for Desktop and mobile that there are no more 4 DIMMS totally in a system:
+    Channel A/ Slot 0 --> Dimm 0 --> SpdAddressTable[0]
+    Channel A/ Slot 1 --> Dimm 1 --> SpdAddressTable[1]
+    Channel B/ Slot 0 --> Dimm 2 --> SpdAddressTable[2]
+    Channel B/ Slot 1 --> Dimm 3 --> SpdAddressTable[3]
+  Refer to SmbiosMemory.c for use
+  If change the mapping rule, please update the Revision number.
+**/
+  UINT8                                           *SpdAddressTable;
+/**
+  Offset 36:
+  Channel A DIMM Slot Mechanical present bit map, bit 0 -> DIMM 0, bit 1 -> DIMM1, ...
+  if the bit is 1, the related DIMM slot is present.
+  E.g. if channel A has 2 DIMMs,  ChannelASlotMap = 0x03;
+  E.g. if channel A has only 1 DIMMs,  ChannelASlotMap = 0x01;
+  Refer to SmbiosMemory.c
+**/
+  UINT8                                           ChannelASlotMap;
+/**
+  Offset 37:
+  Channel B DIMM Slot Mechanical present bit map, bit 0 -> DIMM 0, bit 1 -> DIMM1, ...
+  if the bit is 1, the related DIMM slot is present.
+  E.g. if channel B has 2 DIMMs,  ChannelBSlotMap = 0x03;
+  E.g. if channel B has only 1 DIMMs,  ChannelBSlotMap = 0x01;
+  Refer to SmbiosMemory.c
+**/
+  UINT8                                           ChannelBSlotMap;
+/**
+  Offset 38:
+  MRC execution time measurement: <b>0=Disable</b>, 1=Enable
+**/
+  UINT8                                           MrcTimeMeasure;
+/**
+  Offset 39:
+  Fast boot: 0=Disable, <b>1=Enable</b>
+**/
+  UINT8                                           MrcFastBoot;
+/**
+  Offset 40:
+  Retrieves the OEM custom string for the SMBIOS Type 17 Table DeviceLocator field.
+**/
+  MEMORY_DXE_CONFIG_GET_DEVICE_LOCATOR_STRING     GetDeviceLocatorString;
+/**
+  Offset 48:
+  Retrieves the OEM custom string for the SMBIOS Type 17 Table BankLocator field.
+**/
+  MEMORY_DXE_CONFIG_GET_BANK_LOCATOR_STRING       GetBankLocatorString;
+};
+#pragma pack(pop)
+
+#endif // _MEMORY_DXE_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieDxeConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieDxeConfig.h
new file mode 100644
index 0000000000..799121f1ab
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/ConfigBlock/PcieDxeConfig.h
@@ -0,0 +1,114 @@
+/** @file
+  PCIE DXE policy definitions
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCIE_DXE_CONFIG_H_
+#define _PCIE_DXE_CONFIG_H_
+
+#include "CpuPcieInfo.h"
+
+#pragma pack(push, 1)
+
+#define PCIE_DXE_CONFIG_REVISION 2
+
+typedef struct {
+  UINT16  VendorId; ///< Offset 0 PCI Config space offset 0
+  UINT16  DeviceId; ///< Offset 2 PCI Config space offset 2
+/**
+  Offset 4:
+  SnoopLatency bit definition
+  Note: All Reserved bits must be set to 0
+
+  BIT[15]     - When set to 1b, indicates that the values in bits 9:0 are valid
+                When clear values in bits 9:0 will be ignored
+  BIT[14]     - Should be set to 0b
+  BIT[13]     - Reserved
+  BITS[12:10] - Value in bits 9:0 will be multiplied with the scale in these bits
+                000b - 1 ns
+                001b - 32 ns
+                010b - 1024 ns
+                011b - 32,768 ns
+                100b - 1,048,576 ns
+                101b - 33,554,432 ns
+                110b - Reserved
+                111b - Reserved
+  BITS[9:0]   - Snoop Latency Value. The value in these bits will be multiplied with
+                the scale in bits 12:10
+**/
+  UINT16  SnoopLatency;
+/**
+  Offset 6:
+  NonSnoopLatency bit definition
+  Note: All Reserved bits must be set to 0
+
+  BIT[15]     - When set to 1b, indicates that the values in bits 9:0 are valid
+                When clear values in bits 9:0 will be ignored
+  BIT[14]     - Should be set to 0b
+  BIT[13]     - Reserved
+  BITS[12:10] - Value in bits 9:0 will be multiplied with the scale in these bits
+                000b - 1 ns
+                001b - 32 ns
+                010b - 1024 ns
+                011b - 32,768 ns
+                100b - 1,048,576 ns
+                101b - 33,554,432 ns
+                110b - Reserved
+                111b - Reserved
+  BITS[9:0]   - Non Snoop Latency Value. The value in these bits will be multiplied with
+                the scale in bits 12:10
+**/
+  UINT16  NonSnoopLatency;
+  UINT8   RevId;    ///<   Offset 8 PCI Config space offset 8; 0xFF means all steppings
+  UINT8   Rsvd0[3]; ///<   Offset 9
+} PCIE_LTR_DEV_INFO;
+
+///
+/// PCIE Power Optimizer config
+///
+typedef struct {
+  UINT16  LtrMaxSnoopLatency;   ///< Offset 0 LTR Maximum Snoop Latency: <b>0x0846=70us</b>
+  UINT16  LtrMaxNoSnoopLatency; ///< Offset 2 LTR Maximum Non-Snoop Latency: <b>0x0846=70us</b>
+  UINT8   ObffEnable;           ///< Offset 4 LTR enable/disable: 0=Disable, <b>1=Enable</b>
+  UINT8   LtrEnable;            ///< Offset 5 LTR enable/disable: 0=Disable, <b>1=Enable</b>
+  UINT8   Rsvd0[2];             ///< Offset 6 Reserved
+} CPU_PCIE_PWR_OPT;
+
+
+/**
+  The PCI Express Configuration info includes PCI Resources Range Base and Limits and the control
+  for PEG ASPM.
+  The data elements should be initialized by a Platform Module.\n
+  @note <b>Optional.</b> These policies will be ignored if there is no PEG port present on board.
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  -  Adding PEG RTD3 Support Setup Variable
+  <b>Revision 3</b>:
+  -  Adding CPU PCIE RTD3 Support Setup Variable
+  -  Deprecating PEG RTD3 Support Setup Variable
+  <b>Revision 4</b>:
+  -  Deprecating CPU PCIE RTD3 Support Setup Variable
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER      Header;                         ///< Offset 0-27 Config Block Header
+/**
+  Offset 28: This field is used to describe the ASPM control for PEG Ports\n
+  0=ASPM Disabled, 1=ASPM L0s Enabled, 2=ASPM L1 Enabled, 3=ASPM L0sL1 Enabled, <b>4=ASPM AUTO</b>
+**/
+  UINT8                    PegAspm[SA_PEG_MAX_FUN];
+/**
+  Offset 32: PCIe Hot Plug Enable/Disable. It has 2 policies.
+   - <b>Disabled (0x0)</b>     : No hotplug.
+   - Enabled (0x1)      : Bios assist hotplug.
+**/
+  UINT8                    PegRootPortHPE[SA_PEG_MAX_FUN];
+  CPU_PCIE_PWR_OPT          PegPwrOpt[SA_PEG_MAX_FUN];     ///< Offset 36: This field is used to describe the PCIe LTR/OBFF relevant settings
+  UINT32                   PegRtd3;                       ///  Deprecated Policy
+  UINT8                    CpuPcieRtd3;                   ///< Enable/Disable RTD3 Support for CPU PCIE. 0=Disable and 1=Enable (default)  // Deprecated Policy
+  UINT8                    Rsvd3[3];
+} PCIE_DXE_CONFIG;
+#pragma pack(pop)
+
+#endif // _PCIE_DXE_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/ConfigBlock/PramPreMemConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/ConfigBlock/PramPreMemConfig.h
new file mode 100644
index 0000000000..8947e80b22
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/ConfigBlock/PramPreMemConfig.h
@@ -0,0 +1,34 @@
+/** @file
+  Policy definition for Persisted Ram (Pram) Config Block
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PRAM_PREMEM_CONFIG__H_
+#define _PRAM_PREMEM_CONFIG__H_
+#pragma pack(push, 1)
+
+#define PRAM_PREMEM_CONFIG_REVISION 1
+
+/**
+ Defines Pram configuration parameters.\n
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER  Header;    ///< Offset 0-27 Config Block Header
+  /**
+  Offset 28:
+  Size of Pram
+  If disabled, or if PcdSaOcEnable is disabled, all other policies in this config block are ignored.
+  <b>0=Disable</b>,
+  1=4MB,
+  2=16MB,
+  3=64MB
+  **/
+  UINT8   Pram;
+  UINT8   Rsvd[3];                ///< Offset 29 Reserved for DWORD alignment
+} PRAM_PREMEM_CONFIG;
+#pragma pack(pop)
+
+#endif // _PRAM_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiConfig.h
new file mode 100644
index 0000000000..203d894df9
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiConfig.h
@@ -0,0 +1,24 @@
+/** @file
+  Policy details for miscellaneous configuration in System Agent
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SA_MISC_PEI_CONFIG_H_
+#define _SA_MISC_PEI_CONFIG_H_
+
+#pragma pack(push, 1)
+
+#define SA_MISC_PEI_CONFIG_REVISION 1
+
+/**
+  This configuration block is to configure SA Miscellaneous variables during PEI Post-Mem.\n
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER  Header;               ///< Offset 0-27 Config Block Header
+} SA_MISC_PEI_CONFIG;
+#pragma pack(pop)
+
+#endif // _SA_MISC_PEI_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiPreMemConfig.h b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiPreMemConfig.h
new file mode 100644
index 0000000000..8c660b31a9
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/ConfigBlock/SaMiscPeiPreMemConfig.h
@@ -0,0 +1,104 @@
+/** @file
+  Policy details for miscellaneous configuration in System Agent
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SA_MISC_PEI_PREMEM_CONFIG_H_
+#define _SA_MISC_PEI_PREMEM_CONFIG_H_
+
+#pragma pack(push, 1)
+
+#ifndef MEM_CFG_MAX_SOCKETS
+#define MEM_CFG_MAX_SOCKETS 16
+#endif
+
+#define SA_MISC_PEI_PREMEM_CONFIG_REVISION 2
+
+/**
+  This configuration block is to configure SA Miscellaneous variables during PEI Pre-Mem phase like programming
+  different System Agent BARs, TsegSize, MmioSize required etc.
+  <b>Revision 1</b>:
+  - Initial version.
+  <b>Revision 2</b>:
+  - Deprecate IedSize.
+**/
+typedef struct {
+  CONFIG_BLOCK_HEADER  Header;               ///< Offset 0-27 Config Block Header
+  /**
+    Offset 28 Memory DIMMs' SPD address for reading SPD data.
+    TGL Mapping
+      0 - Controller 0 Channel 0 Dimm 0 - DDR4 - DDR5 - LPDDR4 - LPDDR5
+      1 - Controller 0 Channel 0 Dimm 1 - DDR4
+      2 - Controller 0 Channel 1 Dimm 0 -------- DDR5 - LPDDR4 - LPDDR5
+      3 - Controller 0 Channel 1 Dimm 1 -------- DDR5 2DPC
+      4 - Controller 0 Channel 2 Dimm 0 --------------- LPDDR4 - LPDDR5
+      6 - Controller 0 Channel 3 Dimm 0 --------------- LPDDR4 - LPDDR5
+      8 - Controller 1 Channel 0 Dimm 0 - DDR4 - DDR5 - LPDDR4 - LPDDR5
+      9 - Controller 1 Channel 0 Dimm 1 - DDR4
+     10 - Controller 1 Channel 1 Dimm 0 -------- DDR5 - LPDDR4 - LPDDR5
+     11 - Controller 1 Channel 1 Dimm 1 -------- DDR5 2DPC
+     12 - Controller 1 Channel 2 Dimm 0 --------------- LPDDR4 - LPDDR5
+     14 - Controller 1 Channel 3 Dimm 0 --------------- LPDDR4 - LPDDR5
+  **/
+  UINT8   SpdAddressTable[MEM_CFG_MAX_SOCKETS];
+  VOID    *S3DataPtr;                        ///< Offset 44 Memory data save pointer for S3 resume. The memory space should be allocated and filled with proper S3 resume data on a resume path
+  UINT32  SmbusBar;                          ///< Offset 48 Address of System Agent SMBUS BAR: <b>0xEFA0</b>
+  /**
+    Offset 52 Size of TSEG in bytes. (Must be power of 2)
+    <b>0x400000</b>: 4MB for Release build (When IED enabled, it will be 8MB)
+    0x1000000      : 16MB for Debug build (Regardless IED enabled or disabled)
+  **/
+  UINT32  TsegSize;
+  /**
+    Offset 56
+    <b>(Test)</b> Size of IED region in bytes.
+    <b>0</b> : IED Disabled (no memory occupied)
+    0x400000 : 4MB SMM memory occupied by IED (Part of TSEG)
+    <b>Note: Enabling IED may also enlarge TsegSize together.</b>
+    @deprecated
+  **/
+  UINT32  IedSize;
+  UINT32  SkipExtGfxScan:1;                  ///< <b>(Test)</b> OFfset 60:0 :1=Skip External Gfx Device Scan; <b>0=Scan for external graphics devices</b>. Set this policy to skip External Graphics card scanning if the platform uses Internal Graphics only.
+  UINT32  BdatEnable:1;                      ///< Offset 60:1 :This field enables the generation of the BIOS DATA ACPI Tables: <b>0=FALSE</b>, 1=TRUE.
+  UINT32  TxtImplemented:1;                  ///< OFfset 60:2 :This field currently is used to tell MRC if it should run after TXT initializatoin completed: <b>0=Run without waiting for TXT</b>, 1=Run after TXT initialization by callback
+  /**
+   Offset 60:3 :
+   <b>(Test)</b> Scan External Discrete Graphics Devices for Legacy Only VGA OpROMs
+
+   When enabled, if the primary graphics device is an external discrete graphics device, Si will scan the
+   graphics device for legacy only VGA OpROMs.
+
+   This is intended to ease the implementation of a BIOS feature to automatically enable CSM if the Primary Gfx device
+   only supports Legacy VBIOS (No UEFI GOP Present).  Otherwise disabling CSM won't result in no video being displayed.
+   This is useful for platforms that implement PCIe slots that allow the end user to install an arbitrary Gfx device.
+
+   This setting will only take effect if SkipExtGfxScan == 0.  It is ignored otherwise.
+
+  - Disabled (0x0)         : Don't Scan for Legacy Only VGA OpROMs (Default)
+  - <b>Enabled</b>  (0x1)  : Scan External Gfx for Legacy Only VGA OpROM
+  **/
+  UINT32  ScanExtGfxForLegacyOpRom:1;
+  UINT32  RsvdBits0  :28;                    ///< Offset 60:4 :Reserved for future use
+  UINT8   UserBd;                            ///< Offset 64 <b>0=Mobile/Mobile Halo</b>, 1=Desktop/DT Halo, 5=ULT/ULX/Mobile Halo, 7=UP Server
+  UINT8   LockPTMregs;                       ///< <b>(Test)</b> Offset 65 Lock PCU Thermal Management registers: 0=FALSE, <b>1=TRUE</b>
+  UINT8   BdatTestType;                      ///< Offset 66 When BdatEnable is set to TRUE, this option selects the type of data which will be populated in the BIOS Data ACPI Tables: <b>0=RMT</b>, 1=RMT Per Bit, 2=Margin 2D.
+  UINT8   CridEnable;                        ///< Offset 67 For Platforms supporting Intel(R) SIPP, this policy is use control enable/disable Compatibility Revision ID (CRID) feature: <b>0=FALSE</b>, 1=TRUE
+  UINT32  AcpiReservedMemorySize;            ///< Offset 68 The Size of a Reserved memory buffer allocated in previous boot for S3 resume used. Originally it is retrieved from AcpiVariableCompatibility variable.
+  UINT32  OpRomScanTempMmioBar;              ///< <b>(Test)</b> Offset 72 Temporary address to MMIO map OpROMs during VGA scanning.  Used for ScanExtGfxForLegacyOpRom feature.  MUST BE 16MB ALIGNED!
+  UINT32  OpRomScanTempMmioLimit;            ///< <b>(Test)</b> Offset 76 Limit address for OpROM MMIO range.  Used for ScanExtGfxForLegacyOpRom feature. (OpROMScanTempMmioLimit - OpRomScanTempMmioBar) MUST BE >= 16MB!
+  UINT64  AcpiReservedMemoryBase;            ///< Offset 80 The Base address of a Reserved memory buffer allocated in previous boot for S3 resume used. Originally it is retrieved from AcpiVariableCompatibility variable.
+  UINT64  SystemMemoryLength;                ///< Offset 88 Total system memory length from previous boot, this is required for S3 resume. Originally it is retrieved from AcpiVariableCompatibility variable.
+
+  UINT8   WrcFeatureEnable;                   ///< Offset 96: Enable/Disable WRC (Write Cache) feature of IOP. When enabled, supports IO devices allocating onto the ring and into LLC.
+  UINT8   Reserved1[3];                       ///< Reserved for config block alignment.
+
+
+  // Since the biggest element is UINT64, this structure should be aligned with 64 bits.
+  UINT8   Rsvd[4];                           ///< Reserved for config block alignment.
+
+
+} SA_MISC_PEI_PREMEM_CONFIG;
+#pragma pack(pop)
+
+#endif // _SA_MISC_PEI_PREMEM_CONFIG_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/Library/SaPlatformLib.h b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/Library/SaPlatformLib.h
new file mode 100644
index 0000000000..daf3746605
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/Library/SaPlatformLib.h
@@ -0,0 +1,48 @@
+/** @file
+  Header file for SaPlatformLib.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_PLATFORM_LIB_H_
+#define _SA_PLATFORM_LIB_H_
+
+
+/**
+  Checks if SKU is Mobile
+
+  @retval FALSE  SKU is not Mobile
+  @retval TRUE   SKU is Mobile
+**/
+BOOLEAN
+EFIAPI
+IsMobileSku (
+  VOID
+  );
+
+/**
+  Checks if SKU is Desktop
+
+  @retval FALSE  SKU is not Desktop
+  @retval TRUE   SKU is Desktop
+**/
+BOOLEAN
+EFIAPI
+IsDesktopSku (
+  VOID
+  );
+
+/**
+  Checks if SKU is Server
+
+  @retval FALSE  SKU is not Server
+  @retval TRUE   SKU is Server
+**/
+BOOLEAN
+EFIAPI
+IsServerSku (
+  VOID
+  );
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/MemInfoHob.h b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/MemInfoHob.h
new file mode 100644
index 0000000000..f280a3d379
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/MemInfoHob.h
@@ -0,0 +1,245 @@
+/** @file
+  This file contains definitions required for creation of
+  Memory S3 Save data, Memory Info data and Memory Platform
+  data hobs.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _MEM_INFO_HOB_H_
+#define _MEM_INFO_HOB_H_
+
+#pragma pack (push, 1)
+
+extern EFI_GUID gSiMemoryS3DataGuid;
+extern EFI_GUID gSiMemoryInfoDataGuid;
+extern EFI_GUID gSiMemoryPlatformDataGuid;
+
+#define MAX_TRACE_CACHE_TYPE  3
+
+#define MAX_NODE        2
+#define MAX_CH          4
+#define MAX_DIMM        2
+
+///
+/// Host reset states from MRC.
+///
+#define  WARM_BOOT        2
+
+#define R_MC_CHNL_RANK_PRESENT  0x7C
+#define   B_RANK0_PRS           BIT0
+#define   B_RANK1_PRS           BIT1
+#define   B_RANK2_PRS           BIT4
+#define   B_RANK3_PRS           BIT5
+
+///
+/// Defines taken from MRC so avoid having to include MrcInterface.h
+///
+
+//
+// Matches MAX_SPD_SAVE define in MRC
+//
+#ifndef MAX_SPD_SAVE
+#define MAX_SPD_SAVE 29
+#endif
+
+//
+// MRC version description.
+//
+typedef struct {
+  UINT8  Major;     ///< Major version number
+  UINT8  Minor;     ///< Minor version number
+  UINT8  Rev;       ///< Revision number
+  UINT8  Build;     ///< Build number
+} SiMrcVersion;
+
+//
+// Matches MrcDimmSts enum in MRC
+//
+#ifndef DIMM_ENABLED
+#define DIMM_ENABLED     0  // DIMM/rank Pair is enabled, presence will be detected.
+#endif
+#ifndef DIMM_DISABLED
+#define DIMM_DISABLED    1  // DIMM/rank Pair is disabled, regardless of presence.
+#endif
+#ifndef DIMM_PRESENT
+#define DIMM_PRESENT     2  // There is a DIMM present in the slot/rank pair and it will be used.
+#endif
+#ifndef DIMM_NOT_PRESENT
+#define DIMM_NOT_PRESENT 3  // There is no DIMM present in the slot/rank pair.
+#endif
+
+//
+// Matches MrcBootMode enum in MRC
+//
+#ifndef __MRC_BOOT_MODE__
+#define __MRC_BOOT_MODE__                 //The below values are originated from MrcCommonTypes.h
+  #ifndef INT32_MAX
+  #define INT32_MAX                       (0x7FFFFFFF)
+  #endif  //INT32_MAX
+typedef enum {
+  bmCold,                                 ///< Cold boot
+  bmWarm,                                 ///< Warm boot
+  bmS3,                                   ///< S3 resume
+  bmFast,                                 ///< Fast boot
+  MrcBootModeMax,                         ///< MRC_BOOT_MODE enumeration maximum value.
+  MrcBootModeDelim = INT32_MAX            ///< This value ensures the enum size is consistent on both sides of the PPI.
+} MRC_BOOT_MODE;
+#endif  //__MRC_BOOT_MODE__
+
+//
+// Matches MrcDdrType enum in MRC
+//
+#ifndef MRC_DDR_TYPE_DDR4
+#define MRC_DDR_TYPE_DDR4     0
+#endif
+#ifndef MRC_DDR_TYPE_DDR3
+#define MRC_DDR_TYPE_DDR3     1
+#endif
+#ifndef MRC_DDR_TYPE_LPDDR3
+#define MRC_DDR_TYPE_LPDDR3   2
+#endif
+#ifndef MRC_DDR_TYPE_LPDDR4
+#define MRC_DDR_TYPE_LPDDR4   3
+#endif
+#ifndef MRC_DDR_TYPE_WIO2
+#define MRC_DDR_TYPE_WIO2     4
+#endif
+#ifndef MRC_DDR_TYPE_UNKNOWN
+#define MRC_DDR_TYPE_UNKNOWN  5
+#endif
+
+#define MAX_PROFILE_NUM     4 // number of memory profiles supported
+#define MAX_XMP_PROFILE_NUM 2 // number of XMP profiles supported
+
+//
+// DIMM timings
+//
+typedef struct {
+  UINT32 tCK;       ///< Memory cycle time, in femtoseconds.
+  UINT16 NMode;     ///< Number of tCK cycles for the channel DIMM's command rate mode.
+  UINT16 tCL;       ///< Number of tCK cycles for the channel DIMM's CAS latency.
+  UINT16 tCWL;      ///< Number of tCK cycles for the channel DIMM's minimum CAS write latency time.
+  UINT16 tFAW;      ///< Number of tCK cycles for the channel DIMM's minimum four activate window delay time.
+  UINT16 tRAS;      ///< Number of tCK cycles for the channel DIMM's minimum active to precharge delay time.
+  UINT16 tRCDtRP;   ///< Number of tCK cycles for the channel DIMM's minimum RAS# to CAS# delay time and Row Precharge delay time.
+  UINT16 tREFI;     ///< Number of tCK cycles for the channel DIMM's minimum Average Periodic Refresh Interval.
+  UINT16 tRFC;      ///< Number of tCK cycles for the channel DIMM's minimum refresh recovery delay time.
+  UINT16 tRFCpb;    ///< Number of tCK cycles for the channel DIMM's minimum per bank refresh recovery delay time.
+  UINT16 tRFC2;     ///< Number of tCK cycles for the channel DIMM's minimum refresh recovery delay time.
+  UINT16 tRFC4;     ///< Number of tCK cycles for the channel DIMM's minimum refresh recovery delay time.
+  UINT16 tRPab;     ///< Number of tCK cycles for the channel DIMM's minimum row precharge delay time for all banks.
+  UINT16 tRRD;      ///< Number of tCK cycles for the channel DIMM's minimum row active to row active delay time.
+  UINT16 tRRD_L;    ///< Number of tCK cycles for the channel DIMM's minimum row active to row active delay time for same bank groups.
+  UINT16 tRRD_S;    ///< Number of tCK cycles for the channel DIMM's minimum row active to row active delay time for different bank groups.
+  UINT16 tRTP;      ///< Number of tCK cycles for the channel DIMM's minimum internal read to precharge command delay time.
+  UINT16 tWR;       ///< Number of tCK cycles for the channel DIMM's minimum write recovery time.
+  UINT16 tWTR;      ///< Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time.
+  UINT16 tWTR_L;    ///< Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time for same bank groups.
+  UINT16 tWTR_S;    ///< Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time for different bank groups.
+  UINT16 tCCD_L;  ///< Number of tCK cycles for the channel DIMM's minimum CAS-to-CAS delay for same bank group.
+} MRC_CH_TIMING;
+
+///
+/// Memory SMBIOS & OC Memory Data Hob
+///
+typedef struct {
+  UINT8            Status;                  ///< See MrcDimmStatus for the definition of this field.
+  UINT8            DimmId;
+  UINT32           DimmCapacity;            ///< DIMM size in MBytes.
+  UINT16           MfgId;
+  UINT8            ModulePartNum[20];       ///< Module part number for DDR3 is 18 bytes however for DRR4 20 bytes as per JEDEC Spec, so reserving 20 bytes
+  UINT8            RankInDimm;              ///< The number of ranks in this DIMM.
+  UINT8            SpdDramDeviceType;       ///< Save SPD DramDeviceType information needed for SMBIOS structure creation.
+  UINT8            SpdModuleType;           ///< Save SPD ModuleType information needed for SMBIOS structure creation.
+  UINT8            SpdModuleMemoryBusWidth; ///< Save SPD ModuleMemoryBusWidth information needed for SMBIOS structure creation.
+  UINT8            SpdSave[MAX_SPD_SAVE];   ///< Save SPD Manufacturing information needed for SMBIOS structure creation.
+  UINT16           Speed;                   ///< The maximum capable speed of the device, in MHz
+  UINT8            MdSocket;                ///< MdSocket: 0 = Memory Down, 1 = Socketed. Needed for SMBIOS structure creation.
+} DIMM_INFO;
+
+typedef struct {
+  UINT8            Status;                  ///< Indicates whether this channel should be used.
+  UINT8            ChannelId;
+  UINT8            DimmCount;               ///< Number of valid DIMMs that exist in the channel.
+  MRC_CH_TIMING    Timing[MAX_PROFILE_NUM]; ///< The channel timing values.
+  DIMM_INFO        DimmInfo[MAX_DIMM];      ///< Save the DIMM output characteristics.
+} CHANNEL_INFO;
+
+typedef struct {
+  UINT8            Status;                  ///< Indicates whether this controller should be used.
+  UINT16           DeviceId;                ///< The PCI device id of this memory controller.
+  UINT8            RevisionId;              ///< The PCI revision id of this memory controller.
+  UINT8            ChannelCount;            ///< Number of valid channels that exist on the controller.
+  CHANNEL_INFO     ChannelInfo[MAX_CH];     ///< The following are channel level definitions.
+} CONTROLLER_INFO;
+
+typedef struct {
+  UINT64   BaseAddress;   ///< Trace Base Address
+  UINT64   TotalSize;     ///< Total Trace Region of Same Cache type
+  UINT8    CacheType;     ///< Trace Cache Type
+  UINT8    ErrorCode;     ///< Trace Region Allocation Fail Error code
+  UINT8    Rsvd[2];
+} PSMI_MEM_INFO;
+
+typedef struct {
+  UINT8             Revision;
+  UINT16            DataWidth;              ///< Data width, in bits, of this memory device
+  /** As defined in SMBIOS 3.0 spec
+    Section 7.18.2 and Table 75
+  **/
+  UINT8             MemoryType;             ///< DDR type: DDR3, DDR4, or LPDDR3
+  UINT16            MaximumMemoryClockSpeed;///< The maximum capable speed of the device, in megahertz (MHz)
+  UINT16            ConfiguredMemoryClockSpeed; ///< The configured clock speed to the memory device, in megahertz (MHz)
+  /** As defined in SMBIOS 3.0 spec
+    Section 7.17.3 and Table 72
+  **/
+  UINT8             ErrorCorrectionType;
+
+  SiMrcVersion      Version;
+  BOOLEAN           EccSupport;
+  UINT8             MemoryProfile;
+  UINT32            TotalPhysicalMemorySize;
+  UINT32            DefaultXmptCK[MAX_XMP_PROFILE_NUM];///< Stores the tCK value read from SPD XMP profiles if they exist.
+  UINT8             XmpProfileEnable;                  ///< If XMP capable DIMMs are detected, this will indicate which XMP Profiles are common among all DIMMs.
+  UINT8             Ratio;
+  UINT8             RefClk;
+  UINT32            VddVoltage[MAX_PROFILE_NUM];
+  CONTROLLER_INFO   Controller[MAX_NODE];
+} MEMORY_INFO_DATA_HOB;
+
+/**
+  Memory Platform Data Hob
+
+  <b>Revision 1:</b>
+  - Initial version.
+  <b>Revision 2:</b>
+  - Added TsegBase, PrmrrSize, PrmrrBase, Gttbase, MmioSize, PciEBaseAddress fields
+**/
+typedef struct {
+  UINT8             Revision;
+  UINT8             Reserved[3];
+  UINT32            BootMode;
+  UINT32            TsegSize;
+  UINT32            TsegBase;
+  UINT32            PrmrrSize;
+  UINT64            PrmrrBase;
+  UINT32            PramSize;
+  UINT64            PramBase;
+  UINT64            DismLimit;
+  UINT64            DismBase;
+  UINT32            GttBase;
+  UINT32            MmioSize;
+  UINT32            PciEBaseAddress;
+  PSMI_MEM_INFO     PsmiInfo[MAX_TRACE_CACHE_TYPE];
+} MEMORY_PLATFORM_DATA;
+
+typedef struct {
+  EFI_HOB_GUID_TYPE    EfiHobGuidType;
+  MEMORY_PLATFORM_DATA Data;
+  UINT8                *Buffer;
+} MEMORY_PLATFORM_DATA_HOB;
+
+#pragma pack (pop)
+
+#endif // _MEM_INFO_HOB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/Protocol/SaPolicy.h b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/Protocol/SaPolicy.h
new file mode 100644
index 0000000000..4ff2578038
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Include/Protocol/SaPolicy.h
@@ -0,0 +1,61 @@
+/** @file
+  Interface definition details between System Agent and platform drivers during DXE phase.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SA_POLICY_H_
+#define _SA_POLICY_H_
+
+#include <ConfigBlock.h>
+#include <Library/ConfigBlockLib.h>
+#include <GraphicsConfig.h>
+#include <ConfigBlock/MemoryDxeConfig.h>
+#include <ConfigBlock/PcieDxeConfig.h>
+#include <VtdConfig.h>
+
+///
+/// Extern the GUID for protocol users.
+///
+extern EFI_GUID gSaPolicyProtocolGuid;
+extern EFI_GUID gGraphicsDxeConfigGuid;
+extern EFI_GUID gPcieDxeConfigGuid;
+extern EFI_GUID gMemoryDxeConfigGuid;
+extern EFI_GUID gVtdDxeConfigGuid;
+
+/**
+  Don't change the original SA_POLICY_PROTOCOL_REVISION macro, external
+  modules maybe have consumed this macro in their source code.  Directly
+  update the SA_POLICY_PROTOCOL_REVISION version number may cause those
+  external modules to auto mark themselves wrong version info.
+  Always create new version macro for new Policy protocol interface.
+**/
+#define SA_POLICY_PROTOCOL_REVISION  1
+
+#define CPU_PCIE_DEV_END_OF_TABLE                0xFFFF
+
+#define LTR_MAX_SNOOP_LATENCY_VALUE             0x0846    ///< Intel recommended maximum value for Snoop Latency
+#define LTR_MAX_NON_SNOOP_LATENCY_VALUE         0x0846    ///< Intel recommended maximum value for Non-Snoop Latency
+
+
+/**
+  SA DXE Policy
+
+ The SA_POLICY_PROTOCOL producer drvier is recommended to
+ set all the SA_POLICY_PROTOCOL size buffer zero before init any member parameter,
+ this clear step can make sure no random value for those unknow new version parameters.
+
+ Make sure to update the Revision if any change to the protocol, including the existing
+ internal structure definations.\n
+  Note: Here revision will be bumped up when adding/removing any config block under this structure.\n
+  <b>Revision 1</b>:
+  - Initial version.
+**/
+typedef struct {
+  CONFIG_BLOCK_TABLE_HEADER      TableHeader;    ///< Offset 0-31
+/*
+  Individual Config Block Structures are added here in memory as part of AddConfigBlock()
+*/
+} SA_POLICY_PROTOCOL;
+
+#endif
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 08/40] TigerlakeSiliconPkg/SystemAgent: Add IncludePrivate headers
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (5 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 07/40] TigerlakeSiliconPkg/SystemAgent: Add include headers Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 09/40] TigerlakeSiliconPkg/Fru: Add TglCpu/Include headers Heng Luo
                   ` (31 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following header files:
  * SystemAgent/IncludePrivate

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/IncludePrivate/Protocol/SaIotrapSmi.h |  42 ++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/IncludePrivate/Protocol/SaNvsArea.h   |  30 ++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/IncludePrivate/SaConfigHob.h          |  50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/IncludePrivate/SaNvsAreaDef.h         | 222 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 344 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/IncludePrivate/Protocol/SaIotrapSmi.h b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/IncludePrivate/Protocol/SaIotrapSmi.h
new file mode 100644
index 0000000000..2e86d497f9
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/IncludePrivate/Protocol/SaIotrapSmi.h
@@ -0,0 +1,42 @@
+/** @file
+  This file defines the SA Iotrap SMI Protocol to provide the
+  I/O address for registered Iotrap SMI.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SA_IOTRAP_SMI_PROTOCOL_H_
+#define _SA_IOTRAP_SMI_PROTOCOL_H_
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID                       gSaIotrapSmiProtocolGuid;
+
+#define SA_IOTRAP_SMI_PROTOCOL_REVISION_1 1
+
+//
+// SA IO Trap SMI Protocol definition (Private protocol for RC internal use only)
+//
+typedef struct {
+/*
+ Protocol revision number
+ Any backwards compatible changes to this protocol will result in an update in the revision number
+ Major changes will require publication of a new protocol
+
+  <b>Revision 1</b>:
+    - First version
+*/
+  UINT8   Revision;
+  UINT16  SaIotrapSmiAddress;
+} SA_IOTRAP_SMI_PROTOCOL;
+
+///
+/// Pcie Trap valid types
+///
+typedef enum {
+  CpuPciePmTrap,
+  CpuPcieTrapTypeMaximum
+} CPU_PCIE_TRAP_TYPE;
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/IncludePrivate/Protocol/SaNvsArea.h b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/IncludePrivate/Protocol/SaNvsArea.h
new file mode 100644
index 0000000000..785a808cf4
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/IncludePrivate/Protocol/SaNvsArea.h
@@ -0,0 +1,30 @@
+/** @file
+  Definition of the System Agent global NVS area protocol.
+  This protocol publishes the address and format of a global ACPI NVS buffer
+  used as a communications buffer between SMM/DXE/PEI code and ASL code.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SYSTEM_AGENT_NVS_AREA_H_
+#define _SYSTEM_AGENT_NVS_AREA_H_
+
+//
+// SA NVS Area definition
+//
+#include <SaNvsAreaDef.h>
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gSaNvsAreaProtocolGuid;
+
+///
+/// System Agent Global NVS Area Protocol
+///
+typedef struct {
+  SYSTEM_AGENT_NVS_AREA *Area;        ///< System Agent Global NVS Area Structure
+} SYSTEM_AGENT_NVS_AREA_PROTOCOL;
+
+#endif // _SYSTEM_AGENT_NVS_AREA_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/IncludePrivate/SaConfigHob.h b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/IncludePrivate/SaConfigHob.h
new file mode 100644
index 0000000000..65622069e6
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/IncludePrivate/SaConfigHob.h
@@ -0,0 +1,50 @@
+/** @file
+  The GUID definition for SaConfigHob
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SA_CONFIG_HOB_H_
+#define _SA_CONFIG_HOB_H_
+
+#include <Register/SaRegsHostBridge.h>
+#include <Base.h>
+#include "CpuPcieInfo.h"
+#include <Library/PcdLib.h>
+
+extern EFI_GUID gSaConfigHobGuid;
+#define SA_VTD_ENGINE_NUMBER        3
+
+#pragma pack (push,1)
+///
+/// DPR Directory Types
+///
+typedef enum {
+  EnumDprDirectoryTxt   = 0,
+} DPR_DIRECTORY_ELEMENT;
+
+#define DPR_DIRECTORY_TYPE_TXT          0x01      ///< DPR directory type - TXT
+#define DPR_DIRECTORY_TYPE_BIOSGUARD    0x02      ///< DPR directory type - BIOS Guard
+#define DPR_DIRECTORY_MAX               1         ///< DPR Maximum Size
+
+///
+/// DPR directory entry definition
+///
+typedef struct {
+  UINT8   Type;          ///< DPR Directory Type
+  UINT8   Size;          ///< DPR Size in MB
+  UINT32  PhysBase;      ///< Must be 4K aligned (bits 11..0 must be clear)
+  UINT16  Reserved;      ///< Must be 0
+} DPR_DIRECTORY_ENTRY;
+
+///
+/// System Agent Config Hob
+///
+typedef struct {
+  EFI_HOB_GUID_TYPE        EfiHobGuidType;                           ///< GUID Hob type structure for gSaConfigHobGuid
+  DPR_DIRECTORY_ENTRY      DprDirectory[DPR_DIRECTORY_MAX];          ///< DPR directory entry definition
+  UINT8                    ApertureSize;                             ///< Aperture size value
+  BOOLEAN                  CridEnable;                               ///< This field inidicates if CRID is enabled or disabled (to support Intel(R) SIPP)
+} SA_CONFIG_HOB;
+#pragma pack (pop)
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/IncludePrivate/SaNvsAreaDef.h b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/IncludePrivate/SaNvsAreaDef.h
new file mode 100644
index 0000000000..6ee2343363
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/IncludePrivate/SaNvsAreaDef.h
@@ -0,0 +1,222 @@
+//
+// Automatically generated by GenNvs ver 2.4.6
+// Please DO NOT modify !!!
+//
+
+/** @file
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+  //
+  // Define SA NVS Area operation region.
+  //
+#ifndef _SA_NVS_AREA_DEF_H_
+#define _SA_NVS_AREA_DEF_H_
+
+#pragma pack (push,1)
+typedef struct {
+  UINT32   IgdOpRegionAddress;                      ///< Offset 0       IGD OpRegion base address
+  UINT8    GfxTurboIMON;                            ///< Offset 4       IMON Current Value
+  UINT8    IgdState;                                ///< Offset 5       IGD State (Primary Display = 1)
+  UINT8    IgdBootType;                             ///< Offset 6       IGD Boot Display Device
+  UINT8    IgdPanelType;                            ///< Offset 7       IGD Panel Type CMOS option
+  UINT8    IgdPanelScaling;                         ///< Offset 8       IGD Panel Scaling
+  UINT8    IgdBiaConfig;                            ///< Offset 9       IGD BIA Configuration
+  UINT8    IgdSscConfig;                            ///< Offset 10      IGD SSC Configuration
+  UINT8    IgdDvmtMemSize;                          ///< Offset 11      IGD DVMT Memory Size
+  UINT8    IgdFunc1Enable;                          ///< Offset 12      IGD Function 1 Enable
+  UINT8    IgdHpllVco;                              ///< Offset 13      HPLL VCO
+  UINT8    IgdSciSmiMode;                           ///< Offset 14      GMCH SMI/SCI mode (0=SCI)
+  UINT8    IgdPAVP;                                 ///< Offset 15      IGD PAVP data
+  UINT8    CurrentDeviceList;                       ///< Offset 16      Current Attached Device List
+  UINT16   CurrentDisplayState;                     ///< Offset 17      Current Display State
+  UINT16   NextDisplayState;                        ///< Offset 19      Next Display State
+  UINT8    NumberOfValidDeviceId;                   ///< Offset 21      Number of Valid Device IDs
+  UINT32   DeviceId1;                               ///< Offset 22      Device ID 1
+  UINT32   DeviceId2;                               ///< Offset 26      Device ID 2
+  UINT32   DeviceId3;                               ///< Offset 30      Device ID 3
+  UINT32   DeviceId4;                               ///< Offset 34      Device ID 4
+  UINT32   DeviceId5;                               ///< Offset 38      Device ID 5
+  UINT32   DeviceId6;                               ///< Offset 42      Device ID 6
+  UINT32   DeviceId7;                               ///< Offset 46      Device ID 7
+  UINT32   DeviceId8;                               ///< Offset 50      Device ID 8
+  UINT32   DeviceId9;                               ///< Offset 54      Device ID 9
+  UINT32   DeviceId10;                              ///< Offset 58      Device ID 10
+  UINT32   DeviceId11;                              ///< Offset 62      Device ID 11
+  UINT32   DeviceId12;                              ///< Offset 66      Device ID 12
+  UINT32   DeviceId13;                              ///< Offset 70      Device ID 13
+  UINT32   DeviceId14;                              ///< Offset 74      Device ID 14
+  UINT32   DeviceId15;                              ///< Offset 78      Device ID 15
+  UINT32   DeviceIdX;                               ///< Offset 82      Device ID for eDP device
+  UINT32   NextStateDid1;                           ///< Offset 86      Next state DID1 for _DGS
+  UINT32   NextStateDid2;                           ///< Offset 90      Next state DID2 for _DGS
+  UINT32   NextStateDid3;                           ///< Offset 94      Next state DID3 for _DGS
+  UINT32   NextStateDid4;                           ///< Offset 98      Next state DID4 for _DGS
+  UINT32   NextStateDid5;                           ///< Offset 102     Next state DID5 for _DGS
+  UINT32   NextStateDid6;                           ///< Offset 106     Next state DID6 for _DGS
+  UINT32   NextStateDid7;                           ///< Offset 110     Next state DID7 for _DGS
+  UINT32   NextStateDid8;                           ///< Offset 114     Next state DID8 for _DGS
+  UINT32   NextStateDidEdp;                         ///< Offset 118     Next state DID for eDP
+  UINT8    LidState;                                ///< Offset 122     Lid State (Lid Open = 1)
+  UINT32   AKsv0;                                   ///< Offset 123     First four bytes of AKSV (manufacturing mode)
+  UINT8    AKsv1;                                   ///< Offset 127     Fifth byte of AKSV (manufacturing mode)
+  UINT8    BrightnessPercentage;                    ///< Offset 128     Brightness Level Percentage
+  UINT8    AlsEnable;                               ///< Offset 129     Ambient Light Sensor Enable
+  UINT8    AlsAdjustmentFactor;                     ///< Offset 130     Ambient Light Adjusment Factor
+  UINT8    LuxLowValue;                             ///< Offset 131     LUX Low Value
+  UINT8    LuxHighValue;                            ///< Offset 132     LUX High Value
+  UINT8    ActiveLFP;                               ///< Offset 133     Active LFP
+  UINT8    IpuAcpiMode;                             ///< Offset 134     IPU ACPI device type (0=Disabled, 1=AVStream virtual device as child of GFX)
+  UINT8    EdpValid;                                ///< Offset 135     Check for eDP display device
+  UINT8    HgMode;                                  ///< Offset 136     SG Mode (0=Disabled, 1=HG Muxed, 2=HG Muxless, 3=DGPU Only)
+  UINT8    HgFeatureList;                           ///< Offset 137     HG Feature List
+  UINT8    Pcie0GpioSupport;                        ///< Offset 138     PCIe0 GPIO Support (0=Disabled, 1=PCH Based, 2=I2C Based)
+  UINT8    Pcie0HoldRstExpanderNo;                  ///< Offset 139     PCIe0 HLD RST IO Expander Number
+  UINT32   Pcie0HoldRstGpioNo;                      ///< Offset 140     PCIe0 HLD RST GPIO Number
+  UINT8    Pcie0HoldRstActiveInfo;                  ///< Offset 144     PCIe0 HLD RST GPIO Active Information
+  UINT8    Pcie0PwrEnExpanderNo;                    ///< Offset 145     PCIe0 PWR Enable IO Expander Number
+  UINT32   Pcie0PwrEnGpioNo;                        ///< Offset 146     PCIe0 PWR Enable GPIO Number
+  UINT8    Pcie0PwrEnActiveInfo;                    ///< Offset 150     PCIe0 PWR Enable GPIO Active Information
+  UINT8    Pcie1GpioSupport;                        ///< Offset 151     PCIe1 GPIO Support (0=Disabled, 1=PCH Based, 2=I2C Based)
+  UINT8    Pcie1HoldRstExpanderNo;                  ///< Offset 152     PCIe1 HLD RST IO Expander Number
+  UINT32   Pcie1HoldRstGpioNo;                      ///< Offset 153     PCIe1 HLD RST GPIO Number
+  UINT8    Pcie1HoldRstActiveInfo;                  ///< Offset 157     PCIe1 HLD RST GPIO Active Information
+  UINT8    Pcie1PwrEnExpanderNo;                    ///< Offset 158     PCIe1 PWR Enable IO Expander Number
+  UINT32   Pcie1PwrEnGpioNo;                        ///< Offset 159     PCIe1 PWR Enable GPIO Number
+  UINT8    Pcie1PwrEnActiveInfo;                    ///< Offset 163     PCIe1 PWR Enable GPIO Active Information
+  UINT8    Pcie2GpioSupport;                        ///< Offset 164     PCIe2 GPIO Support (0=Disabled, 1=PCH Based, 2=I2C Based)
+  UINT8    Pcie2HoldRstExpanderNo;                  ///< Offset 165     PCIe2 HLD RST IO Expander Number
+  UINT32   Pcie2HoldRstGpioNo;                      ///< Offset 166     PCIe2 HLD RST GPIO Number
+  UINT8    Pcie2HoldRstActiveInfo;                  ///< Offset 170     PCIe2 HLD RST GPIO Active Information
+  UINT8    Pcie2PwrEnExpanderNo;                    ///< Offset 171     PCIe2 PWR Enable IO Expander Number
+  UINT32   Pcie2PwrEnGpioNo;                        ///< Offset 172     PCIe2 PWR Enable GPIO Number
+  UINT8    Pcie2PwrEnActiveInfo;                    ///< Offset 176     PCIe2 PWR Enable GPIO Active Information
+  UINT8    Pcie3GpioSupport;                        ///< Offset 177     PCIe3 GPIO Support (0=Disabled, 1=PCH Based, 2=I2C Based)
+  UINT8    Pcie3HoldRstExpanderNo;                  ///< Offset 178     PCIe3 HLD RST IO Expander Number
+  UINT32   Pcie3HoldRstGpioNo;                      ///< Offset 179     PCIe3 HLD RST GPIO Number
+  UINT8    Pcie3HoldRstActiveInfo;                  ///< Offset 183     PCIe3 HLD RST GPIO Active Information
+  UINT8    Pcie3PwrEnExpanderNo;                    ///< Offset 184     PCIe3 PWR Enable IO Expander Number
+  UINT32   Pcie3PwrEnGpioNo;                        ///< Offset 185     PCIe3 PWR Enable GPIO Number
+  UINT8    Pcie3PwrEnActiveInfo;                    ///< Offset 189     PCIe3 PWR Enable GPIO Active Information
+  UINT32   Pcie3WakeGpioNo;                         ///< Offset 190     PCIe3 RTD3 Device Wake GPIO Number
+  UINT16   DelayAfterPwrEn;                         ///< Offset 194     Delay after power enable for PCIe
+  UINT16   DelayAfterHoldReset;                     ///< Offset 196     Delay after Hold Reset for PCIe
+  UINT8    Pcie0EpCapOffset;                        ///< Offset 198     PCIe0 Endpoint Capability Structure Offset
+  UINT32   XPcieCfgBaseAddress;                     ///< Offset 199     Any Device's PCIe Config Space Base Address
+  UINT16   GpioBaseAddress;                         ///< Offset 203     GPIO Base Address
+  UINT32   NvIgOpRegionAddress;                     ///< Offset 205     NVIG opregion address
+  UINT32   NvHmOpRegionAddress;                     ///< Offset 209     NVHM opregion address
+  UINT32   ApXmOpRegionAddress;                     ///< Offset 213     AMDA opregion address
+  UINT8    Peg0LtrEnable;                           ///< Offset 217     Latency Tolerance Reporting Enable
+  UINT8    Peg0ObffEnable;                          ///< Offset 218     Optimized Buffer Flush and Fill
+  UINT8    Peg1LtrEnable;                           ///< Offset 219     Latency Tolerance Reporting Enable
+  UINT8    Peg1ObffEnable;                          ///< Offset 220     Optimized Buffer Flush and Fill
+  UINT8    Peg2LtrEnable;                           ///< Offset 221     Latency Tolerance Reporting Enable
+  UINT8    Peg2ObffEnable;                          ///< Offset 222     Optimized Buffer Flush and Fill
+  UINT8    Peg3LtrEnable;                           ///< Offset 223     Latency Tolerance Reporting Enable
+  UINT8    Peg3ObffEnable;                          ///< Offset 224     Optimized Buffer Flush and Fill
+  UINT16   PegLtrMaxSnoopLatency;                   ///< Offset 225     SA Peg Latency Tolerance Reporting Max Snoop Latency
+  UINT16   PegLtrMaxNoSnoopLatency;                 ///< Offset 227     SA Peg Latency Tolerance Reporting Max No Snoop Latency
+  UINT64   Mmio64Base;                              ///< Offset 229     Base of above 4GB MMIO resource
+  UINT64   Mmio64Length;                            ///< Offset 237     Length of above 4GB MMIO resource
+  UINT32   CpuIdInfo;                               ///< Offset 245     CPU ID info to get Family Id or Stepping
+  UINT32   Mmio32Base;                              ///< Offset 249     Base of below 4GB MMIO resource
+  UINT32   Mmio32Length;                            ///< Offset 253     Length of below 4GB MMIO resource
+  UINT32   Pcie0WakeGpioNo;                         ///< Offset 257     PCIe0 RTD3 Device Wake GPIO Number
+  UINT32   Pcie1WakeGpioNo;                         ///< Offset 261     PCIe1 RTD3 Device Wake GPIO Number
+  UINT32   Pcie2WakeGpioNo;                         ///< Offset 265     PCIe2 RTD3 Device Wake GPIO Number
+  UINT8    VtdDisable;                              ///< Offset 269     VT-d Enable/Disable
+  UINT32   VtdBaseAddress[7];                       ///< Offset 270     VT-d Base Address 1
+                                                    ///< Offset 274     VT-d Base Address 2
+                                                    ///< Offset 278     VT-d Base Address 3
+                                                    ///< Offset 282     VT-d Base Address 4 (iTBT PCIE0)
+                                                    ///< Offset 286     VT-d Base Address 5 (iTBT PCIE1)
+                                                    ///< Offset 290     VT-d Base Address 6 (iTBT PCIE2)
+                                                    ///< Offset 294     VT-d Base Address 7 (iTBT PCIE3)
+  UINT16   VtdEngine1Vid;                           ///< Offset 298     VT-d Engine#1 Vendor ID
+  UINT16   VtdEngine2Vid;                           ///< Offset 300     VT-d Engine#2 Vendor ID
+  UINT8    RootPortIndex;                           ///< Offset 302     RootPort Number
+  UINT32   RootPortAddress;                         ///< Offset 303     RootPortAddress
+  UINT8    CpuTraceHubMode;                         ///< Offset 307     CPU Trace Hub Mode
+  UINT8    SimicsEnvironment;                       ///< Offset 308     Simics Environment information
+  UINT8    ItbtXhciEn;                              ///< Offset 309     TCSS XHCI Device Enable
+  UINT8    ItbtXdciEn;                              ///< Offset 310     TCSS XDCI Device Enable
+  UINT8    ItbtDmaEn[2];                            ///< Offset 311     TCSS DMA 0 Device Enable
+                                                    ///< Offset 312     TCSS DMA 1 Device Enable
+  UINT8    ItbtPcieRpEn[4];                         ///< Offset 313     TCSS ItbtPcieRp PCIE RP 0 Device Enable
+                                                    ///< Offset 314     TCSS ItbtPcieRp PCIE RP 1 Device Enable
+                                                    ///< Offset 315     TCSS ItbtPcieRp PCIE RP 2 Device Enable
+                                                    ///< Offset 316     TCSS ItbtPcieRp PCIE RP 3 Device Enable
+  UINT32   ItbtPcieRpAddress[4];                    ///< Offset 317     TCSS ItbtPcie Root Port address 0
+                                                    ///< Offset 321     TCSS ItbtPcie Root Port address 1
+                                                    ///< Offset 325     TCSS ItbtPcie Root Port address 2
+                                                    ///< Offset 329     TCSS ItbtPcie Root Port address 3
+  UINT32   TcssxDCIPwrDnScale;                      ///< Offset 333     TCSS xDCI Power Down Scale Value, DWC_USB3_GCTL_INIT[31:19]
+  UINT8    TcssxDCIInt;                             ///< Offset 337     TCSS xDCI Int Pin
+  UINT8    TcssxDCIIrq;                             ///< Offset 338     TCSS xDCI Irq Number
+  UINT8    TcssRtd3;                                ///< Offset 339     TCSS RTD3
+  UINT32   TcssDma0RmrrAddr;                        ///< Offset 340     TCSS DMA0 RMRR address
+  UINT32   TcssDma1RmrrAddr;                        ///< Offset 344     TCSS DMA1 RMRR address
+  UINT8    LtrEnable[4];                            ///< Offset 348     Latency Tolerance Reporting Mechanism. <b>0: Disable</b>; 1: Enable.
+                                                    ///< Offset 349     Latency Tolerance Reporting Mechanism. <b>0: Disable</b>; 1: Enable.
+                                                    ///< Offset 350     Latency Tolerance Reporting Mechanism. <b>0: Disable</b>; 1: Enable.
+                                                    ///< Offset 351     Latency Tolerance Reporting Mechanism. <b>0: Disable</b>; 1: Enable.
+  UINT16   PcieLtrMaxSnoopLatency[4];               ///< Offset 352     PCIE LTR max snoop Latency 0
+                                                    ///< Offset 354     PCIE LTR max snoop Latency 1
+                                                    ///< Offset 356     PCIE LTR max snoop Latency 2
+                                                    ///< Offset 358     PCIE LTR max snoop Latency 3
+  UINT16   PcieLtrMaxNoSnoopLatency[4];             ///< Offset 360     PCIE LTR max no snoop Latency 0
+                                                    ///< Offset 362     PCIE LTR max no snoop Latency 1
+                                                    ///< Offset 364     PCIE LTR max no snoop Latency 2
+                                                    ///< Offset 366     PCIE LTR max no snoop Latency 3
+  UINT8    IomReady;                                ///< Offset 368     IOM Ready
+  UINT8    TcssIomVccSt;                            ///< Offset 369     TCSS IOM VccSt
+  UINT8    CpuPcieRp0Enable;                        ///< Offset 370     <0:Disabled, 1:Enabled>
+  UINT8    CpuPcieRp1Enable;                        ///< Offset 371     <0:Disabled, 1:Enabled>
+  UINT8    CpuPcieRp2Enable;                        ///< Offset 372     <0:Disabled, 1:Enabled>
+  UINT8    CpuPcieRp3Enable;                        ///< Offset 373     <0:Disabled, 1:Enabled>
+  UINT8    VmdEnable;                               ///< Offset 374     VMD Device Enable
+  UINT32   DeviceIdY;                               ///< Offset 375     Device ID for second LFP device
+  UINT32   NextStateDidEdp2;                        ///< Offset 379     Next state DID for Second Display
+  UINT8    SlotSelection;                           ///< Offset 383     PCIe slot selection
+  UINT8    VmdRp1to8;                               ///< Offset 384     VMD PCH RP 1 to 8 <0:Disabled, 1:Enabled>
+  UINT8    VmdRp9to16;                              ///< Offset 385     VMD PCH RP 9 to 16 <0:Disabled, 1:Enabled>
+  UINT8    VmdRp17to24;                             ///< Offset 386     VMD PCH RP 17 to 24 <0:Disabled, 1:Enabled>
+  UINT8    VmdSataPort[8];                          ///< Offset 387     VMD SATA PORT 0 <0:Disabled, 1:Enabled>
+                                                    ///< Offset 388     VMD SATA PORT 1 <0:Disabled, 1:Enabled>
+                                                    ///< Offset 389     VMD SATA PORT 2 <0:Disabled, 1:Enabled>
+                                                    ///< Offset 390     VMD SATA PORT 3 <0:Disabled, 1:Enabled>
+                                                    ///< Offset 391     VMD SATA PORT 4 <0:Disabled, 1:Enabled>
+                                                    ///< Offset 392     VMD SATA PORT 5 <0:Disabled, 1:Enabled>
+                                                    ///< Offset 393     VMD SATA PORT 6 <0:Disabled, 1:Enabled>
+                                                    ///< Offset 394     VMD SATA PORT 7 <0:Disabled, 1:Enabled>
+  UINT8    VmdCpuRp;                                ///< Offset 395     VMD CPU RP      <0:Disabled, 1:Enabled>
+  UINT8    CpuPcieRtd3;                             ///< Offset 396     RTD3 Support for CPU PCIE.
+  UINT32   LaneUsed;                                ///< Offset 397     Lane Used of each CSI Port <0:Not Configured, 1:x1, 2:x2, 3:x3 4:x4>
+  UINT32   CsiSpeed;                                ///< Offset 401     Speed of each CSI Port <0:Not configured, 1:<416GMbps, 2:<1.5Gbps, 3:<2.0Gbps, 4:<2.5Gbps, 5:<4Gbps, 6:>4Gbps>
+  UINT8    MaxPegPortNumber;                        ///< Offset 405     Max PEG port number
+  UINT8    MemBootMode;                             ///< Offset 406     Current Memory Boot Mode <0: BOOT_MODE_1LM(Default), 1: BOOT_MODE_2LM, 2: BOOT_MODE_PROVISION>
+  UINT8    DpmemSupport;                            ///< Offset 407     Dynamic PMem Support <0: Disabled, 1:Enabled>
+  UINT64   PmemStartingAddress;                     ///< Offset 408     Private Pmem Starting address
+  UINT64   PmemRangeLength;                         ///< Offset 416     Private Pmem Range Length
+  UINT8    Pcie3EpCapOffset;                        ///< Offset 424     PCIe3 Endpoint Capability Structure Offset
+  UINT8    Pcie0SrcClkNo;                           ///< Offset 425     PCIe0 RTD3 Device Source Clock Number
+  UINT8    Pcie1SrcClkNo;                           ///< Offset 426     PCIe1 RTD3 Device Source Clock Number
+  UINT8    Pcie2SrcClkNo;                           ///< Offset 427     PCIe2 RTD3 Device Source Clock Number
+  UINT8    Pcie3SrcClkNo;                           ///< Offset 428     PCIe2 RTD3 Device Source Clock Number
+  UINT8    Pcie0SecBusNum;                          ///< Offset 429     PCIe0 Secondary Bus Number (PCIe0 Endpoint Bus Number)
+  UINT8    Pcie1SecBusNum;                          ///< Offset 430     PCIe1 Secondary Bus Number (PCIe0 Endpoint Bus Number)
+  UINT8    Pcie2SecBusNum;                          ///< Offset 431     PCIe2 Secondary Bus Number (PCIe0 Endpoint Bus Number)
+  UINT8    Pcie3SecBusNum;                          ///< Offset 432     PCIe2 Secondary Bus Number (PCIe0 Endpoint Bus Number)
+  UINT8    Pcie1EpCapOffset;                        ///< Offset 433     PCIe1 Endpoint Capability Structure Offset
+  UINT8    Pcie2EpCapOffset;                        ///< Offset 434     PCIe2 Endpoint Capability Structure Offset
+  UINT8    IsBridgeDeviceBehindPeg1;                ///< Offset 435     Is bridge device behind PEG1
+  UINT8    IsBridgeDeviceBehindPeg2;                ///< Offset 436     Is bridge device behind PEG2
+  UINT8    IsBridgeDeviceBehindPeg3;                ///< Offset 437     Is bridge device behind PEG3
+  UINT8    HgSlot;                                  ///< Offset 438     Slot selection between PCH/PEG
+} SYSTEM_AGENT_NVS_AREA;
+
+#pragma pack(pop)
+#endif
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 09/40] TigerlakeSiliconPkg/Fru: Add TglCpu/Include headers
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (6 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 08/40] TigerlakeSiliconPkg/SystemAgent: Add IncludePrivate headers Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 10/40] TigerlakeSiliconPkg/Fru: Add TglCpu/IncludePrivate headers Heng Luo
                   ` (30 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following header files:
  * Fru/TglCpu/Include

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Include/Library/CpuPcieInfoFruLib.h |  57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Include/Register/SaRegsHostBridge.h | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Include/TcssInfo.h                  |  12 ++++++++++++
 3 files changed, 214 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Include/Library/CpuPcieInfoFruLib.h b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Include/Library/CpuPcieInfoFruLib.h
new file mode 100644
index 0000000000..89cf952717
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Include/Library/CpuPcieInfoFruLib.h
@@ -0,0 +1,57 @@
+/** @file
+  Header file for CpuPcieInfoFruLib.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _CPU_PCIE_INFO_FRU_LIB_H_
+#define _CPU_PCIE_INFO_FRU_LIB_H_
+
+#include <CpuPcieInfo.h>
+
+#define CPU_PCIE_MAX_ROOT_PORTS       4
+
+#define CPU_PCIE_ULT_ULX_MAX_ROOT_PORT     1
+
+#include <Library/CpuRegbarAccessLib.h>
+
+/**
+  Get CPU Maximum Pcie Root Port Number
+
+  @retval PcieMaxRootPort         Pch Maximum Pcie Root Port Number
+**/
+UINT8
+GetMaxCpuPciePortNum (
+  VOID
+  );
+
+/**
+  Get CPU Pcie Root Port Device and Function Number by Root Port physical Number
+
+  @param[in]  RpNumber              Root port physical number. (0-based)
+  @param[out] RpDev                 Return corresponding root port device number.
+  @param[out] RpFun                 Return corresponding root port function number.
+
+  @retval     EFI_SUCCESS           Root port device and function is retrieved
+  @retval     EFI_INVALID_PARAMETER RpNumber is invalid
+**/
+EFI_STATUS
+EFIAPI
+GetCpuPcieRpDevFun (
+  IN  UINTN   RpNumber,
+  OUT UINTN   *RpDev,
+  OUT UINTN   *RpFun
+  );
+
+/**
+  Gets pci segment base address of PCIe root port.
+
+  @param  RpIndex    Root Port Index (0 based)
+  @return PCIe port  base address.
+**/
+UINT64
+CpuPcieBase (
+  IN  UINT32   RpIndex
+  );
+
+#endif // _CPU_PCIE_INFO_FRU_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Include/Register/SaRegsHostBridge.h b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Include/Register/SaRegsHostBridge.h
new file mode 100644
index 0000000000..32e38fa072
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Include/Register/SaRegsHostBridge.h
@@ -0,0 +1,145 @@
+/** @file
+  Register names for Host Bridge block
+  <b>Conventions</b>:
+  - Prefixes:
+    - Definitions beginning with "R_" are registers
+    - Definitions beginning with "B_" are bits within registers
+    - Definitions beginning with "V_" are meaningful values of bits within the registers
+    - Definitions beginning with "S_" are register sizes
+    - Definitions beginning with "N_" are the bit position
+  - In general, SA registers are denoted by "_SA_" in register names
+  - Registers / bits that are different between SA generations are denoted by
+    "_SA_[generation_name]_" in register/bit names. e.g., "_SA_HSW_"
+  - Registers / bits that are different between SKUs are denoted by "_[SKU_name]"
+    at the end of the register/bit names
+  - Registers / bits of new devices introduced in a SA generation will be just named
+    as "_SA_" without [generation_name] inserted.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SA_REGS_HOST_BRIDGE_H_
+#define _SA_REGS_HOST_BRIDGE_H_
+
+#define SA_SEG_NUM              0x00
+#define V_SA_DEVICE_ID_INVALID  0xFFFF
+//
+// DEVICE 0 (Memory Controller Hub)
+//
+#define SA_MC_BUS          0x00
+#define SA_MC_DEV          0x00
+#define SA_MC_FUN          0x00
+#define V_SA_MC_VID        0x8086
+#define R_SA_MC_DEVICE_ID  0x02
+#define R_SA_MC_CAPID0_B   0xE8
+
+//
+// SA DMI configuration
+//
+
+//
+// Maximum DMI lanes and bundles supported (x8 and 4 lanes)
+//
+#define SA_DMI_MAX_LANE                      0x08
+#define SA_DMI_MAX_BUNDLE                    0x04
+#define SA_DMI_MAX_LANE_VER1                 0x04
+#define SA_DMI_MAX_BUNDLE_VER1               0x02
+
+
+//
+// TigerLake Mobile SA Device IDs B0:D0:F0
+//
+#define V_SA_DEVICE_ID_MB_ULT_1 0x9A14   ///< TigerLake Ult (TGL-U 4+2)
+#define V_SA_DEVICE_ID_MB_ULT_2 0x9A04   ///< TigerLake Ult (TGL-U 2+2)
+
+#define V_SA_DEVICE_ID_MB_ULX_1 0x9A12   ///< TigerLake Ulx (TGL-Y 4+2)
+#define V_SA_DEVICE_ID_MB_ULX_2 0x9A02   ///< TigerLake Ulx (TGL-Y 2+2)
+
+/**
+ <b>Description</b>:
+ - This is the base address for the Host Memory Mapped Configuration space.  There is no physical memory within this 32KB window that can be addressed.  The 32KB reserved by this register does not alias to any PCI 2.3 compliant memory mapped space.  On reset, the Host MMIO Memory Mapped Configuation space is disabled and must be enabled by writing a 1 to MCHBAREN [Dev 0, offset48h, bit 0].
+ - All the bits in this register are locked in LT mode.
+ - The register space contains memory control, initialization, timing, and buffer strength registers; clocking registers; and power and thermal management registers.
+**/
+#define R_SA_MCHBAR  (0x48)
+
+/**
+ <b>Description</b>:
+ - All the bits in this register are LT lockable.
+**/
+#define R_SA_GGC (0x50)
+
+/**
+ Description of GMS (8:15)
+ - This field is used to select the amount of Main Memory that is pre-allocated to support the Internal Graphics device in VGA (non-linear) and Native (linear) modes.  The BIOS ensures that memory is pre-allocated only when Internal graphics is enabled.
+ - This register is also LT lockable.
+ - Valid options are 0 (0x0) to 2048MB (0x40) in multiples of 32 MB
+ - All other values are reserved
+ - Hardware does not clear or set any of these bits automatically based on IGD being disabled/enabled.
+ - BIOS Requirement: BIOS must not set this field to 0h if IVD (bit 1 of this register) is 0.
+**/
+#define N_SA_GGC_GMS_OFFSET  (0x8)
+#define B_SA_GGC_GMS_MASK    (0xff00)
+
+/**
+ Description of GGMS (6:7)
+ - This field is used to select the amount of Main Memory that is pre-allocated to support the Internal Graphics Translation Table.  The BIOS ensures that memory is pre-allocated only when Internal graphics is enabled.
+ - GSM is assumed to be a contiguous physical DRAM space with DSM, and BIOS needs to allocate a contiguous memory chunk.  Hardware will derive the base of GSM from DSM only using the GSM size programmed in the register.
+ - Valid options:
+ - 0h: 0 MB of memory pre-allocated for GTT.
+ - 1h: 2 MB of memory pre-allocated for GTT.
+ - 2h: 4 MB of memory pre-allocated for GTT.
+ - 3h: 8 MB of memory pre-allocated for GTT.
+ - Others: Reserved
+ - Hardware functionality in case of programming this value to Reserved is not guaranteed.
+**/
+#define N_SA_GGC_GGMS_OFFSET  (0x6)
+#define B_SA_GGC_GGMS_MASK    (0xc0)
+#define V_SA_GGC_GGMS_8MB     3
+
+/**
+ Description:
+ - Allows for enabling/disabling of PCI devices and functions that are within the CPU package. The table below the bit definitions describes the behavior of all combinations of transactions to devices controlled by this register.
+  All the bits in this register are LT Lockable.
+**/
+#define R_SA_DEVEN (0x54)
+
+/**
+ Description of D2EN (4:4)
+ - 0:  Bus 0 Device 2 is disabled and hidden
+ - 1:  Bus 0 Device 2 is enabled and visible
+ - This bit will remain 0 if Device 2 capability is disabled.
+**/
+#define B_SA_DEVEN_D2EN_MASK     (0x10)
+
+
+///
+/// Description:
+///  The SMRAMC register controls how accesses to Compatible SMRAM spaces are treated.  The Open, Close and Lock bits function only when G_SMRAME bit is set to 1.  Also, the Open bit must be reset before the Lock bit is set.
+///
+#define R_SA_SMRAMC  (0x88)
+
+///
+/// Description:
+///  This register contains the base address of stolen DRAM memory for the GTT. BIOS determines the base of GTT stolen memory by subtracting the GTT graphics stolen memory size (PCI Device 0 offset 52 bits 9:8) from the Graphics Base of  Data Stolen Memory (PCI Device 0 offset B0 bits 31:20).
+///
+#define R_SA_BGSM  (0xb4)
+
+
+///
+/// Description:
+///  This register contains the Top of low memory address.
+///
+#define R_SA_TOLUD (0xbc)
+
+///
+/// Description of TOLUD (20:31)
+///  This register contains bits 31 to 20 of an address one byte above the maximum DRAM memory below 4G that is usable by the operating system. Address bits 31 down to 20 programmed to 01h implies a minimum memory size of 1MB. Configuration software must set this value to the smaller of the following 2 choices: maximum amount memory in the system minus ME stolen memory plus one byte or the minimum address allocated for PCI memory. Address bits 19:0 are assumed to be 0_0000h for the purposes of address comparison. The Host interface positively decodes an address towards DRAM if the incoming address is less than the value programmed in this register.
+///  The Top of Low Usable DRAM is the lowest address above both Graphics Stolen memory and Tseg. BIOS determines the base of Graphics Stolen Memory by subtracting the Graphics Stolen Memory Size from TOLUD and further decrements by Tseg size to determine base of Tseg. All the Bits in this register are locked in LT mode.
+///  This register must be 1MB aligned when reclaim is enabled.
+///
+#define B_SA_TOLUD_TOLUD_MASK      (0xfff00000)
+#define R_SA_MC_CAPID0_A_OFFSET    0xE4
+#define V_SA_LTR_MAX_SNOOP_LATENCY_VALUE           0x0846  ///< Intel recommended maximum value for Snoop Latency (70us)
+#define V_SA_LTR_MAX_NON_SNOOP_LATENCY_VALUE       0x0846  ///< Intel recommended maximum value for Non-Snoop Latency (70us)
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Include/TcssInfo.h b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Include/TcssInfo.h
new file mode 100644
index 0000000000..cd8d57d948
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Include/TcssInfo.h
@@ -0,0 +1,12 @@
+/** @file
+  Register names for TCSS USB devices
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _TCSS_INFO_H_
+#define _TCSS_INFO_H_
+
+#define MAX_ITBT_PCIE_PORT        4
+
+#endif
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 10/40] TigerlakeSiliconPkg/Fru: Add TglCpu/IncludePrivate headers
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (7 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 09/40] TigerlakeSiliconPkg/Fru: Add TglCpu/Include headers Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 11/40] TigerlakeSiliconPkg/Fru: Add TglPch/Include headers Heng Luo
                   ` (29 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following header files:
  * Fru/TglCpu/IncludePrivate

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/IncludePrivate/Library/VtdInitFruLib.h | 18 ++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/IncludePrivate/Register/CpuPcieRegs.h  | 24 ++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/IncludePrivate/Register/IgdRegs.h      | 42 ++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/IncludePrivate/Register/IpuRegs.h      | 31 +++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/IncludePrivate/Register/VtdRegs.h      | 22 ++++++++++++++++++++++
 5 files changed, 137 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/IncludePrivate/Library/VtdInitFruLib.h b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/IncludePrivate/Library/VtdInitFruLib.h
new file mode 100644
index 0000000000..a46b29cbbe
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/IncludePrivate/Library/VtdInitFruLib.h
@@ -0,0 +1,18 @@
+/** @file
+  Vtd Initialization Fru Library header file
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _VTD_INIT_FRU_LIB_H_
+#define _VTD_INIT_FRU_LIB_H_
+
+///
+/// TCSS DMA controller RMRR buffer 4MB for each DMA controller
+///
+#define RMRR_TCSS_DMA_SIZE  0x400000
+
+extern UINT16  mDevEnMap[][2];
+extern UINTN   mDevEnMapSize;
+
+#endif // _VTD_INIT_FRU_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/IncludePrivate/Register/CpuPcieRegs.h b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/IncludePrivate/Register/CpuPcieRegs.h
new file mode 100644
index 0000000000..a571381202
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/IncludePrivate/Register/CpuPcieRegs.h
@@ -0,0 +1,24 @@
+/** @file
+  This file contains definitions of  PCIe Configuration
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_PCIE_REGS_H_
+#define _CPU_PCIE_REGS_H_
+
+#define  R_PCIE_LCAP                              0x4C
+#define  R_PCIE_LCTL                              0x50
+#define  R_PCIE_LSTS                              0x52
+#define  R_PCIE_SLCAP                             0x54
+#define  R_PCIE_SLSTS                             0x5A
+#define  R_PCIE_LCTL2                             0x70
+#define  R_PCIE_MPC                               0xD8
+#define  B_PCIE_MPC_HPME                          BIT1
+#define  R_PCIE_PGTHRES                           0x5C0
+#define  B_PCIE_PGTHRES_L1PGLTREN                 BIT0
+#define  R_PCIE_LCTL3                             0xA34
+#define  B_PCIE_LCTL3_PE                          BIT0
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/IncludePrivate/Register/IgdRegs.h b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/IncludePrivate/Register/IgdRegs.h
new file mode 100644
index 0000000000..f0b30107f4
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/IncludePrivate/Register/IgdRegs.h
@@ -0,0 +1,42 @@
+/** @file
+  Register names for IGD block
+  <b>Conventions</b>:
+  - Prefixes:
+    - Definitions beginning with "R_" are registers
+    - Definitions beginning with "B_" are bits within registers
+    - Definitions beginning with "V_" are meaningful values of bits within the registers
+    - Definitions beginning with "S_" are register sizes
+    - Definitions beginning with "N_" are the bit position
+  - In general, SA registers are denoted by "_SA_" in register names
+  - Registers / bits that are different between SA generations are denoted by
+    "_SA_[generation_name]_" in register/bit names. e.g., "_SA_HSW_"
+  - Registers / bits that are different between SKUs are denoted by "_[SKU_name]"
+    at the end of the register/bit names
+  - Registers / bits of new devices introduced in a SA generation will be just named
+    as "_SA_" without [generation_name] inserted.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _IGD_REGS_H_
+#define _IGD_REGS_H_
+
+///
+/// Device 2 Register Equates
+///
+//
+// The following equates must be reviewed and revised when the specification is ready.
+//
+#define IGD_BUS_NUM          0x00
+#define IGD_DEV_NUM          0x02
+#define IGD_FUN_NUM          0x00
+
+///
+/// GTTMMADR aligned to 16MB (Base address = [38:24])
+///
+#define R_SA_IGD_GTTMMADR          0x10
+
+#define R_SA_IGD_SWSCI_OFFSET      0x00E8
+#define R_SA_IGD_ASLS_OFFSET       0x00FC  ///< ASL Storage
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/IncludePrivate/Register/IpuRegs.h b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/IncludePrivate/Register/IpuRegs.h
new file mode 100644
index 0000000000..afc72e8db0
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/IncludePrivate/Register/IpuRegs.h
@@ -0,0 +1,31 @@
+/** @file
+  Register names for IPU block
+  <b>Conventions</b>:
+  - Prefixes:
+    - Definitions beginning with "R_" are registers
+    - Definitions beginning with "B_" are bits within registers
+    - Definitions beginning with "V_" are meaningful values of bits within the registers
+    - Definitions beginning with "S_" are register sizes
+    - Definitions beginning with "N_" are the bit position
+  - IPU registers are denoted by "_IPU_" in register names
+  - Registers / bits that are different between IPU generations are denoted by
+    "_IPU_[generation_name]_" in register/bit names. e.g., "_IPU_TGL_"
+  - Registers / bits that are different between SKUs are denoted by "_[SKU_name]"
+    at the end of the register/bit names
+  - Registers / bits of new devices introduced in a IPU generation will be just named
+    as "_IPU_" without [generation_name] inserted.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _IPU_REGS_H_
+#define _IPU_REGS_H_
+
+//
+// Device 5 Equates
+//
+#define IPU_BUS_NUM    0x00
+#define IPU_DEV_NUM    0x05
+#define IPU_FUN_NUM    0x00
+
+#endif  // _IPU_REGS_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/IncludePrivate/Register/VtdRegs.h b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/IncludePrivate/Register/VtdRegs.h
new file mode 100644
index 0000000000..d796a44afc
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/IncludePrivate/Register/VtdRegs.h
@@ -0,0 +1,22 @@
+/** @file
+  Register names for VTD block
+  <b>Conventions</b>:
+  - Prefixes:
+    - Definitions beginning with "R_" are registers
+    - Definitions beginning with "B_" are bits within registers
+    - Definitions beginning with "V_" are meaningful values of bits within the registers
+    - Definitions beginning with "S_" are register sizes
+    - Definitions beginning with "N_" are the bit position
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _VTD_REGS_H_
+#define _VTD_REGS_H_
+
+///
+/// Vt-d Engine base address.
+///
+#define R_MCHBAR_VTD1_OFFSET                 0x5400  ///< HW UNIT1 for IGD
+#define R_MCHBAR_VTD3_OFFSET                 0x5410  ///< HW UNIT3 for all other - PEG, USB, SATA etc
+
+#endif
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 11/40] TigerlakeSiliconPkg/Fru: Add TglPch/Include headers
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (8 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 10/40] TigerlakeSiliconPkg/Fru: Add TglCpu/IncludePrivate headers Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 12/40] TigerlakeSiliconPkg/Fru: Add TglPch/IncludePrivate headers Heng Luo
                   ` (28 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following header files:
  * Fru/TglPch/Include

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/Include/PchBdfAssignment.h     | 326 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/Include/PchPcieRpInfo.h        |  16 ++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/Include/PchReservedResources.h |  55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 397 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/Include/PchBdfAssignment.h b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/Include/PchBdfAssignment.h
new file mode 100644
index 0000000000..0d00f25d5e
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/Include/PchBdfAssignment.h
@@ -0,0 +1,326 @@
+/** @file
+  Header file for TigerLake PCH devices PCI Bus Device Function map.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_BDF_ASSIGNMENT_H_
+#define _PCH_BDF_ASSIGNMENT_H_
+
+#define NOT_PRESENT                     0xFF
+
+#define MAX_SATA_CONTROLLER             1
+
+//
+// PCH PCIe Controllers
+//
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_1          28
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_2          28
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_3          28
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_4          28
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_5          28
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_6          28
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_7          28
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_8          28
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_9          29
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_10         29
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_11         29
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_12         29
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_13         29
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_14         29
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_15         29
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_16         29
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_17         27
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_18         27
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_19         27
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_20         27
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_21         27
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_22         27
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_23         27
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_24         27
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_25         NOT_PRESENT
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_26         NOT_PRESENT
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_27         NOT_PRESENT
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_28         NOT_PRESENT
+
+//
+// USB3 (XHCI) Controller PCI config
+//
+#define PCI_DEVICE_NUMBER_PCH_XHCI                    20
+#define PCI_FUNCTION_NUMBER_PCH_XHCI                  0
+
+//
+// xDCI (OTG) USB Device Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_XDCI                    20
+#define PCI_FUNCTION_NUMBER_PCH_XDCI                  1
+
+//
+//  Thermal Device
+//
+#define PCI_DEVICE_NUMBER_PCH_THERMAL                 NOT_PRESENT
+#define PCI_FUNCTION_NUMBER_PCH_THERMAL               NOT_PRESENT
+
+//
+// CSME HECI #1
+//
+#define PCI_DEVICE_NUMBER_PCH_HECI1                   22
+#define PCI_FUNCTION_NUMBER_PCH_HECI1                 0
+
+//
+// CSME HECI #2
+//
+#define PCI_DEVICE_NUMBER_PCH_HECI2                   22
+#define PCI_FUNCTION_NUMBER_PCH_HECI2                 1
+
+//
+// CSME IDE-Redirection (IDE-R)
+//
+#define PCI_DEVICE_NUMBER_PCH_IDER                    22
+#define PCI_FUNCTION_NUMBER_PCH_IDER                  2
+
+//
+// CSME Keyboard and Text (KT) Redirection
+//
+#define PCI_DEVICE_NUMBER_PCH_KTR                     22
+#define PCI_FUNCTION_NUMBER_PCH_KTR                   3
+
+//
+// CSME HECI #3
+//
+#define PCI_DEVICE_NUMBER_PCH_HECI3                   22
+#define PCI_FUNCTION_NUMBER_PCH_HECI3                 4
+
+//
+// CSME HECI #4
+//
+#define PCI_DEVICE_NUMBER_PCH_HECI4                   22
+#define PCI_FUNCTION_NUMBER_PCH_HECI4                 5
+
+//
+// CSME MROM
+//
+#define PCI_DEVICE_NUMBER_PCH_MROM                    NOT_PRESENT
+#define PCI_FUNCTION_NUMBER_PCH_MROM                  NOT_PRESENT
+
+//
+// CSME WLAN
+//
+#define PCI_DEVICE_NUMBER_PCH_WLAN                    22
+#define PCI_FUNCTION_NUMBER_PCH_WLAN                  7
+
+//
+// SATA Controllers
+//
+#define PCI_DEVICE_NUMBER_PCH_SATA_1                  23
+#define PCI_FUNCTION_NUMBER_PCH_SATA_1                0
+#define PCI_DEVICE_NUMBER_PCH_SATA_2                  NOT_PRESENT
+#define PCI_FUNCTION_NUMBER_PCH_SATA_2                NOT_PRESENT
+#define PCI_DEVICE_NUMBER_PCH_SATA_3                  NOT_PRESENT
+#define PCI_FUNCTION_NUMBER_PCH_SATA_3                NOT_PRESENT
+
+//
+//  PCH LP Serial IO I2C #0 Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C0          21
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C0        0
+
+//
+//  PCH LP Serial IO I2C #1 Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C1          21
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C1        1
+
+//
+//  PCH LP Serial IO I2C #2 Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C2          21
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C2        2
+
+//
+//  PCH LP Serial IO I2C #3 Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C3          21
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C3        3
+
+//
+//  PCH LP Serial IO I2C #4 Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C4          25
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C4        0
+
+//
+//  PCH LP Serial IO I2C #5 Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C5          25
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C5        1
+
+//
+//  PCH LP Serial IO I2C #6 Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C6          16
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C6        0
+
+//
+//  PCH LP Serial IO I2C #7 Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C7          16
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C7        1
+
+//
+//  PCH LP Serial IO SPI #0 Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI0          30
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI0        2
+
+//
+//  PCH LP Serial IO SPI #1 Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI1          30
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI1        3
+
+//
+//  PCH LP Serial IO SPI #2 Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI2          18
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI2        6
+
+//
+//  PCH LP Serial IO SPI #3 Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI3          19
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI3        0
+
+//
+//  PCH LP Serial IO SPI #4 Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI4          19
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI4        1
+
+//
+//  PCH LP Serial IO SPI #5 Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI5          19
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI5        2
+
+//
+//  PCH LP Serial IO SPI #6 Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI6          19
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI6        3
+
+//
+//  PCH LP Serial IO UART #0 Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART0         30
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART0       0
+
+//
+//  PCH LP Serial IO UART #1 Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART1         30
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART1       1
+
+//
+//  PCH LP Serial IO UART #2 Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART2         25
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART2       2
+
+//
+//  PCH LP Serial IO UART #3 Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART3         17
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART3       0
+
+//
+//  PCH LP Serial IO UART #4 Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART4         17
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART4       1
+
+//
+//  PCH LP Serial IO UART #5 Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART5         17
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART5       2
+
+//
+//  PCH LP Serial IO UART #6 Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART6         17
+#define PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART6       3
+
+//
+// DMA-SMBus Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_DMA_SMBUS               30
+#define PCI_FUNCTION_NUMBER_PCH_DMA_SMBUS             4
+
+//
+// TSN GbE Controller #1
+//
+#define PCI_DEVICE_NUMBER_PCH_TSN0                    30
+#define PCI_FUNCTION_NUMBER_PCH_TSN0                  4
+
+//
+// TSN GbE Controller #2
+//
+#define PCI_DEVICE_NUMBER_PCH_TSN1                    30
+#define PCI_FUNCTION_NUMBER_PCH_TSN1                  5
+
+//
+// LPC Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_LPC                     31
+#define PCI_FUNCTION_NUMBER_PCH_LPC                   0
+
+//
+// eSPI Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_ESPI                    31
+#define PCI_FUNCTION_NUMBER_PCH_ESPI                  0
+
+//
+// Primary to Sideband (P2SB) Bridge
+//
+#define PCI_DEVICE_NUMBER_PCH_P2SB                    31
+#define PCI_FUNCTION_NUMBER_PCH_P2SB                  1
+
+//
+// PMC (D31:F2)
+//
+#define PCI_DEVICE_NUMBER_PCH_PMC                     31
+#define PCI_FUNCTION_NUMBER_PCH_PMC                   2
+
+//
+// PMC SSRAM Registers
+//
+#define PCI_DEVICE_NUMBER_PCH_PMC_SSRAM               20
+#define PCI_FUNCTION_NUMBER_PCH_PMC_SSRAM             2
+
+//
+// HD-A Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_HDA                     31
+#define PCI_FUNCTION_NUMBER_PCH_HDA                   3
+
+//
+// SMBus Controller
+//
+#define PCI_DEVICE_NUMBER_PCH_SMBUS                   31
+#define PCI_FUNCTION_NUMBER_PCH_SMBUS                 4
+
+//
+// SPI Controller (D31:F5)
+//
+#define PCI_DEVICE_NUMBER_PCH_SPI                     31
+#define PCI_FUNCTION_NUMBER_PCH_SPI                   5
+
+//
+// Gigabit Ethernet LAN Controller (D31:F6)
+//
+#define PCI_DEVICE_NUMBER_GBE                         31
+#define PCI_FUNCTION_NUMBER_GBE                       6
+
+#endif // _PCH_BDF_ASSIGNMENT_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/Include/PchPcieRpInfo.h b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/Include/PchPcieRpInfo.h
new file mode 100644
index 0000000000..d3548796a3
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/Include/PchPcieRpInfo.h
@@ -0,0 +1,16 @@
+/** @file
+  Pcie Root Port info header
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_PCIERP_INFO_H_
+#define _PCH_PCIERP_INFO_H_
+
+//
+// Number of PCIe ports per PCIe controller
+//
+#define PCH_PCIE_CONTROLLER_PORTS                     4u
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/Include/PchReservedResources.h b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/Include/PchReservedResources.h
new file mode 100644
index 0000000000..283246692f
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/Include/PchReservedResources.h
@@ -0,0 +1,55 @@
+/** @file
+  PCH preserved MMIO resource definitions.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_PRESERVED_RESOURCES_H_
+#define _PCH_PRESERVED_RESOURCES_H_
+
+/**
+  Detailed recommended static allocation
+  +-------------------------------------------------------------------------+
+  | PCH preserved MMIO range, 32 MB, from 0xFC800000 to 0xFE7FFFFF          |
+  +-------------------------------------------------------------------------+
+  | Size        | Start       | End         | Usage                         |
+  | 8 MB        | 0xFC800000  | 0xFCFFFFFF  | TraceHub SW BAR               |
+  | 16 MB       | 0xFD000000  | 0xFDFFFFFF  | SBREG                         |
+  | 64 KB       | 0xFE000000  | 0xFE00FFFF  | PMC MBAR                      |
+  | 4 KB        | 0xFE010000  | 0xFE010FFF  | SPI BAR0                      |
+  | 176 KB      | 0xFE020000  | 0xFE04BFFF  | SerialIo BAR in ACPI mode     |
+  | 400 KB      | 0xFE04C000  | 0xFE0AFFFF  | Unused                        |
+  | 64 KB       | 0xFE0B0000  | 0xFE0BFFFF  | eSPI LGMR BAR                 |
+  | 64 KB       | 0xFE0C0000  | 0xFE0CFFFF  | eSPI2 SEGMR BAR               |
+  | 192 KB      | 0xFE0D0000  | 0xFE0FFFFF  | Unused                        |
+  | 1 MB        | 0xFE100000  | 0xFE1FFFFF  | TraceHub MTB BAR              |
+  | 2 MB        | 0xFE200000  | 0xFE3FFFFF  | TraceHub FW BAR               |
+  | 2 MB        | 0xFE400000  | 0xFE5FFFFF  | Unused                        |
+  | 2 MB        | 0xFE600000  | 0xFE7FFFFF  | Temp address                  |
+  +-------------------------------------------------------------------------+
+**/
+#define PCH_PRESERVED_BASE_ADDRESS      0xFC800000     ///< Pch preserved MMIO base address
+#define PCH_PRESERVED_MMIO_SIZE         0x02000000     ///< 32MB
+#define PCH_TRACE_HUB_SW_BASE_ADDRESS   0xFC800000     ///< TraceHub SW MMIO base address
+#define PCH_TRACE_HUB_SW_MMIO_SIZE      0x00800000     ///< 8MB
+#define PCH_PCR_BASE_ADDRESS            0xFD000000     ///< SBREG MMIO base address
+#define PCH_PCR_MMIO_SIZE               0x01000000     ///< 16MB
+#define PCH_PWRM_BASE_ADDRESS           0xFE000000     ///< PMC MBAR MMIO base address
+#define PCH_PWRM_MMIO_SIZE              0x00010000     ///< 64KB
+#define PCH_SPI_BASE_ADDRESS            0xFE010000     ///< SPI BAR0 MMIO base address
+#define PCH_SPI_MMIO_SIZE               0x00001000     ///< 4KB
+#define PCH_SERIAL_IO_BASE_ADDRESS      0xFE020000     ///< SerialIo MMIO base address
+#define PCH_SERIAL_IO_MMIO_SIZE         0x0002C000     ///< 176KB
+#define PCH_ESPI_LGMR_BASE_ADDRESS      0xFE0B0000     ///< eSPI LGMR MMIO base address
+#define PCH_ESPI_LGMR_MMIO_SIZE         0x00010000     ///< 64KB
+#define PCH_ESPI_SEGMR_BASE_ADDRESS     0xFE0C0000     ///< Second eSPI GMR MMIO base address
+#define PCH_ESPI_SEGMR_MMIO_SIZE        0x00010000     ///< 64KB
+#define PCH_TRACE_HUB_MTB_BASE_ADDRESS  0xFE100000     ///< TraceHub MTB MMIO base address
+#define PCH_TRACE_HUB_MTB_MMIO_SIZE     0x00100000     ///< 1MB
+#define PCH_TRACE_HUB_FW_BASE_ADDRESS   0xFE200000     ///< TraceHub FW MMIO base address
+#define PCH_TRACE_HUB_FW_MMIO_SIZE      0x00200000     ///< 2MB
+#define PCH_TEMP_BASE_ADDRESS           0xFE600000     ///< preserved temp address for misc usage,
+#define PCH_TEMP_MMIO_SIZE              0x00200000     ///< 2MB
+
+#endif // _PCH_PRESERVED_RESOURCES_H_
+
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 12/40] TigerlakeSiliconPkg/Fru: Add TglPch/IncludePrivate headers
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (9 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 11/40] TigerlakeSiliconPkg/Fru: Add TglPch/Include headers Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 13/40] TigerlakeSiliconPkg/IpBlock: Add Cnvi component Heng Luo
                   ` (27 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following header files:
  * Fru/TglPch/IncludePrivate

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/IncludePrivate/Register/PchPcrRegs.h | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/IncludePrivate/Register/PchPcrRegs.h b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/IncludePrivate/Register/PchPcrRegs.h
new file mode 100644
index 0000000000..4987d21f09
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/IncludePrivate/Register/PchPcrRegs.h
@@ -0,0 +1,66 @@
+/** @file
+  Register names for PCH private chipset register
+
+Conventions:
+
+  - Register definition format:
+    Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpace_RegisterName
+  - Prefix:
+    Definitions beginning with "R_" are registers
+    Definitions beginning with "B_" are bits within registers
+    Definitions beginning with "V_" are meaningful values within the bits
+    Definitions beginning with "S_" are register size
+    Definitions beginning with "N_" are the bit position
+  - [GenerationName]:
+    Three letter acronym of the generation is used (e.g. SKL,KBL,CNL etc.).
+    Register name without GenerationName applies to all generations.
+  - [ComponentName]:
+    This field indicates the component name that the register belongs to (e.g. PCH, SA etc.)
+    Register name without ComponentName applies to all components.
+    Register that is specific to -LP denoted by "_PCH_LP_" in component name.
+  - SubsystemName:
+    This field indicates the subsystem name of the component that the register belongs to
+    (e.g. PCIE, USB, SATA, GPIO, PMC etc.).
+  - RegisterSpace:
+    MEM - MMIO space register of subsystem.
+    IO  - IO space register of subsystem.
+    PCR - Private configuration register of subsystem.
+    CFG - PCI configuration space register of subsystem.
+  - RegisterName:
+    Full register name.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_REGS_PCR_H_
+#define _PCH_REGS_PCR_H_
+
+/**
+  Definition for SBI PID
+  The PCH_SBI_PID defines the PID for PCR MMIO programming and PCH SBI programming as well.
+**/
+#define PID_CNVI       0x73
+#define PID_ICLK       0xAD
+#define PID_DMI        0x88
+#define PID_PSTH       0x89
+#define PID_ESPISPI    0x72
+#define PID_SPF        0x85
+#define PID_SPE        0x84
+#define PID_SPD        0x83
+#define PID_SPC        0x82
+#define PID_SPB        0x81
+#define PID_SPA        0x80
+#define PID_PSF6       0x7F
+#define PID_PSF4       0xBD
+#define PID_PSF3       0xBC
+#define PID_PSF2       0xBB
+#define PID_PSF1       0xBA
+#define PID_GPIOCOM0   0x6E
+#define PID_GPIOCOM1   0x6D
+#define PID_GPIOCOM2   0x6C
+#define PID_GPIOCOM3   0x6B
+#define PID_GPIOCOM4   0x6A
+#define PID_GPIOCOM5   0x69
+#define PID_CSME_PSF   0x8F
+
+#endif
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 13/40] TigerlakeSiliconPkg/IpBlock: Add Cnvi component
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (10 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 12/40] TigerlakeSiliconPkg/Fru: Add TglPch/IncludePrivate headers Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 14/40] TigerlakeSiliconPkg/IpBlock: Add CpuPcieRp component Heng Luo
                   ` (26 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * IpBlock/Cnvi/IncludePrivate

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Cnvi/IncludePrivate/CnviConfigHob.h | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Cnvi/IncludePrivate/CnviConfigHob.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Cnvi/IncludePrivate/CnviConfigHob.h
new file mode 100644
index 0000000000..e881e49d62
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Cnvi/IncludePrivate/CnviConfigHob.h
@@ -0,0 +1,27 @@
+/** @file
+  This file defines the CNVi CONFIG HOB
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _CNVI_CONFIG_HOB_H_
+#define _CNVI_CONFIG_HOB_H_
+
+#include <Base.h>
+
+extern EFI_GUID gCnviConfigHobGuid;
+#pragma pack (push,1)
+
+/**
+  This HOB is used to pass CNVi related private information to DXE phase
+**/
+typedef struct {
+  EFI_HOB_GUID_TYPE EfiHobGuidType; ///< GUID HOB type structure for gCnviConfigHobGuid
+  UINT32 Mode           :  1; ///< 0: Disabled, <b>1: Auto</b>
+  UINT32 BtCore         :  1; ///< 0: Disabled, <b>1: Enabled</b>
+  UINT32 BtAudioOffload :  1; ///< <b>0: Disabled</b>, 1: Enabled
+  UINT32 RsvdBits0      : 29; ///< Reserved bits
+} CNVI_CONFIG_HOB;
+#pragma pack (pop)
+
+#endif // _CNVI_CONFIG_HOB_H_
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 14/40] TigerlakeSiliconPkg/IpBlock: Add CpuPcieRp component
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (11 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 13/40] TigerlakeSiliconPkg/IpBlock: Add Cnvi component Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 15/40] TigerlakeSiliconPkg/IpBlock: Add Espi component Heng Luo
                   ` (25 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * IpBlock/CpuPcieRp/Include
  * IpBlock/CpuPcieRp/IncludePrivate
  * IpBlock/CpuPcieRp/Library
  * IpBlock/CpuPcieRp/LibraryPrivate

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Include/CpuPcieInfo.h                                                   |  31 +++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Include/Library/CpuPcieInitCommon.h                                     | 353 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Include/Library/CpuPcieRpLib.h                                          |  47 +++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/IncludePrivate/Library/DxeCpuPcieRpLib.h                                |  18 ++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Library/PeiDxeSmmCpuPcieInitCommonLib/CpuPcieInitCommon.c               | 445 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Library/PeiDxeSmmCpuPcieInitCommonLib/PeiDxeSmmCpuPcieInitCommonLib.inf |  33 +++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Library/PeiDxeSmmCpuPcieRpLib/CpuPcieRpLib.c                            |  48 ++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Library/PeiDxeSmmCpuPcieRpLib/PeiDxeSmmCpuPcieRpLib.inf                 |  32 ++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/LibraryPrivate/DxeCpuPcieRpLib/DxeCpuPcieRpLib.c                        |  62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/LibraryPrivate/DxeCpuPcieRpLib/DxeCpuPcieRpLib.inf                      |  40 ++++++++++++++++++++++++++++++++++++++++
 10 files changed, 1109 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Include/CpuPcieInfo.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Include/CpuPcieInfo.h
new file mode 100644
index 0000000000..15eeab0ecf
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Include/CpuPcieInfo.h
@@ -0,0 +1,31 @@
+/** @file
+  This file contains definitions of PCIe controller information
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _CPU_PCIE_INFO_H_
+#define _CPU_PCIE_INFO_H_
+
+#define PCIE_HWEQ_COEFFS_MAX    5
+
+//
+// Device 1 Memory Mapped IO Register Offset Equates
+//
+#define SA_PEG_DEV_NUM     0x01
+#define SA_PEG0_DEV_NUM    SA_PEG_DEV_NUM
+#define SA_PEG3_DEV_NUM    0x06
+
+//
+// SA PCI Express* Port configuration
+//
+
+#define CPU_PCIE_MAX_ROOT_PORTS            4
+
+#define SA_PEG_MAX_FUN           0x04
+#define SA_PEG_MAX_LANE          0x14
+#define SA_PEG_MAX_FUN_GEN3      0x03
+#define SA_PEG_MAX_LANE_GEN3     0x10
+#define SA_PEG_MAX_BUNDLE_GEN3   0x08
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Include/Library/CpuPcieInitCommon.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Include/Library/CpuPcieInitCommon.h
new file mode 100644
index 0000000000..79b255c273
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Include/Library/CpuPcieInitCommon.h
@@ -0,0 +1,353 @@
+/** @file
+Header file for CpuPcieInitCommonLib.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _CPU_PCIE_INIT_COMMON_H_
+#define _CPU_PCIE_INIT_COMMON_H_
+
+#include <Library/CpuRegbarAccessLib.h>
+
+/**
+  Print registers value
+
+  @param[in] PrintMmioBase       Mmio base address
+  @param[in] PrintSize           Number of registers
+  @param[in] OffsetFromBase      Offset from mmio base address
+
+  @retval None
+**/
+VOID
+SaPrintRegisters (
+  IN  UINTN        PrintMmioBase,
+  IN  UINT32       PrintSize,
+  IN  UINT32       OffsetFromBase
+  );
+
+/**
+  Print registers value
+
+  @param[in] PrintPciSegmentBase Pci segment base address
+  @param[in] PrintSize           Number of registers
+  @param[in] OffsetFromBase      Offset from mmio base address
+
+  @retval None
+**/
+VOID
+SaPrintPciRegisters (
+  IN  UINT64       PrintPciSegmentBase,
+  IN  UINT32       PrintSize,
+  IN  UINT32       OffsetFromBase
+  );
+
+//
+// 2LM: PegPcie APIs for Sideband Access Mechanism in 2LM mode
+//
+/**
+Reads an 8-bit PCI configuration register.
+
+Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+Other calls to this function will be routed to core PciSegmentRead8 function.
+
+@param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+
+@return The 8-bit PCI configuration register specified by Address.
+
+**/
+UINT8
+EFIAPI
+PegPciSegmentRead8 (
+  IN UINT64                    Address
+  );
+
+/**
+Writes an 8-bit PCI configuration register.
+
+Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+Other calls to this function will be routed to core PciSegmentWrite8 function.
+
+@param  Address     Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+@param  Value       The value to write.
+
+@return The value written to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PegPciSegmentWrite8 (
+  IN UINT64                    Address,
+  IN UINT8                     Value
+  );
+
+/**
+Reads a 16-bit PCI configuration register.
+
+Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+Other calls to this function will be routed to core PciSegmentRead16 function.
+
+@param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+
+@return The 16-bit PCI configuration register specified by Address.
+
+**/
+UINT16
+EFIAPI
+PegPciSegmentRead16 (
+  IN UINT64                    Address
+  );
+
+/**
+Writes a 16-bit PCI configuration register.
+
+Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+Other calls to this function will be routed to core PciSegmentWrite16 function.
+
+@param  Address     Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+@param  Value       The value to write.
+
+@return The parameter of Value.
+
+**/
+UINT16
+EFIAPI
+PegPciSegmentWrite16  (
+  IN UINT64                    Address,
+  IN UINT16                    Value
+  );
+
+/**
+Reads a 32-bit PCI configuration register.
+
+Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+Other calls to this function will be routed to core PciSegmentRead32 function.
+
+@param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+
+@return The 32-bit PCI configuration register specified by Address.
+
+**/
+UINT32
+EFIAPI
+PegPciSegmentRead32 (
+  IN UINT64                    Address
+  );
+
+/**
+Writes a 32-bit PCI configuration register.
+
+Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+Other calls to this function will be routed to core PciSegmentWrite32 function.
+
+@param  Address     Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+@param  Value       The value to write.
+
+@return The parameter of Value.
+
+**/
+UINT32
+EFIAPI
+PegPciSegmentWrite32 (
+  IN UINT64                    Address,
+  IN UINT32                    Value
+  );
+
+/**
+Performs a bitwise OR of a 16-bit PCI configuration register with a 16-bit value.
+
+Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+Other calls to this function will be routed to core PciSegmentOr16 function.
+
+@param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+@param  OrData    The value to OR with the PCI configuration register.
+
+@return The value written to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PegPciSegmentOr16 (
+  IN UINT64                    Address,
+  IN UINT16                    OrData
+  );
+
+/**
+Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value.
+
+Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+Other calls to this function will be routed to core PciSegmentAnd32 function.
+
+@param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+@param  AndData   The value to AND with the PCI configuration register.
+
+@return The value written to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PegPciSegmentAnd16 (
+  IN UINT64                    Address,
+  IN UINT16                    AndData
+  );
+
+/**
+Performs a bitwise AND of a 8-bit PCI configuration register with a 8-bit value.
+
+Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+Other calls to this function will be routed to core PciSegmentAnd8 function.
+
+@param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+@param  AndData   The value to AND with the PCI configuration register.
+
+@return The value written to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PegPciSegmentAnd8 (
+  IN UINT64                    Address,
+  IN UINT8                     AndData
+  );
+
+/**
+Performs a bitwise OR of a 32-bit PCI configuration register with a 32-bit value.
+
+Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+Other calls to this function will be routed to core PciSegmentOr32 function.
+
+@param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+@param  OrData    The value to OR with the PCI configuration register.
+
+@return The value written to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PegPciSegmentOr32 (
+  IN UINT64                    Address,
+  IN UINT32                    OrData
+  );
+
+/**
+Performs a bitwise OR of a 8-bit PCI configuration register with a 8-bit value.
+
+Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+Other calls to this function will be routed to core PciSegmentOr8 function.
+
+@param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+@param  OrData    The value to OR with the PCI configuration register.
+
+@return The value written to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PegPciSegmentOr8 (
+  IN UINT64                    Address,
+  IN UINT8                     OrData
+  );
+
+/**
+Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value.
+
+Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+Other calls to this function will be routed to core PciSegmentAnd32 function.
+
+@param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+@param  AndData   The value to AND with the PCI configuration register.
+
+@return The value written to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PegPciSegmentAnd32 (
+  IN UINT64                    Address,
+  IN UINT32                    AndData
+  );
+
+/**
+Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value,
+followed a  bitwise OR with another 32-bit value.
+
+Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+Other calls to this function will be routed to core PciSegmentAndThenOr32 function.
+
+@param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+@param  AndData   The value to AND with the PCI configuration register.
+@param  OrData    The value to OR with the PCI configuration register.
+
+@return The value written to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PegPciSegmentAndThenOr32 (
+  IN UINT64                    Address,
+  IN UINT32                    AndData,
+  IN UINT32                    OrData
+  );
+
+/**
+Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value,
+followed a  bitwise OR with another 16-bit value.
+
+Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+Other calls to this function will be routed to core PciSegmentAndThenOr16 function.
+
+@param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+@param  AndData   The value to AND with the PCI configuration register.
+@param  OrData    The value to OR with the PCI configuration register.
+
+@return The value written to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PegPciSegmentAndThenOr16 (
+  IN UINT64                    Address,
+  IN UINT16                    AndData,
+  IN UINT16                    OrData
+  );
+
+/**
+Performs a bitwise AND of a 8-bit PCI configuration register with a 8-bit value,
+followed a  bitwise OR with another 8-bit value.
+
+Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+Other calls to this function will be routed to core PciSegmentAndThenOr8 function.
+
+@param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+@param  AndData   The value to AND with the PCI configuration register.
+@param  OrData    The value to OR with the PCI configuration register.
+
+@return The value written to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PegPciSegmentAndThenOr8 (
+  IN UINT64                    Address,
+  IN UINT8                     AndData,
+  IN UINT8                     OrData
+  );
+
+/**
+Find the Offset to a Capabilities ID
+@param[in] Segment              Pci Segment Number
+@param[in] Bus                  Pci Bus Number
+@param[in] Device               Pci Device Number
+@param[in] Function             Pci Function Number
+@param[in] CapId                CAPID to search for
+
+@retval 0                       CAPID not found
+@retval Other                   CAPID found, Offset of desired CAPID
+**/
+UINT8
+PegPcieFindCapId (
+  IN UINT8   Segment,
+  IN UINT8   Bus,
+  IN UINT8   Device,
+  IN UINT8   Function,
+  IN UINT8   CapId
+  );
+#endif // _CPU_PCIE_INIT_COMMON_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Include/Library/CpuPcieRpLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Include/Library/CpuPcieRpLib.h
new file mode 100644
index 0000000000..ebb568193a
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Include/Library/CpuPcieRpLib.h
@@ -0,0 +1,47 @@
+/** @file
+  Header file for CpuPcieRpLib.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _CPU_PCIERP_LIB_H_
+#define _CPU_PCIERP_LIB_H_
+
+#include <Ppi/SiPolicy.h>
+#include <Library/HobLib.h>
+
+#pragma pack(1)
+
+typedef struct {
+  UINT8   Segment;
+  UINT8   Bus;
+  UINT8   Device;
+  UINT8   Function;
+  BOOLEAN Enable;
+} CPU_PCIE_RP_INFO;
+
+#pragma pack()
+
+/**
+  Determines whether PCIe link is active
+
+  @param[in] RpBase    Root Port base address
+  @retval Link Active state
+**/
+BOOLEAN
+CpuPcieIsLinkActive (
+  UINT64  RpBase
+  );
+
+/**
+  Get max PCIe link speed supported by the root port.
+
+  @param[in] RpBase    Root Port pci segment base address
+  @return    Max link speed
+**/
+UINT32
+CpuPcieGetMaxLinkSpeed (
+  UINT64 RpBase
+  );
+
+#endif // _CPU_PCIERP_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/IncludePrivate/Library/DxeCpuPcieRpLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/IncludePrivate/Library/DxeCpuPcieRpLib.h
new file mode 100644
index 0000000000..593e1893bb
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/IncludePrivate/Library/DxeCpuPcieRpLib.h
@@ -0,0 +1,18 @@
+/** @file
+  Header file for private DxeCpuPcieRpLib.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _DXE_PCIE_RP_INIT_LIB_H_
+#define _DXE_PCIE_RP_INIT_LIB_H_
+
+/**
+  Update CPU PCIE RP NVS AREA tables
+
+**/
+VOID
+UpdateCpuPcieNVS (
+  VOID
+  );
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Library/PeiDxeSmmCpuPcieInitCommonLib/CpuPcieInitCommon.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Library/PeiDxeSmmCpuPcieInitCommonLib/CpuPcieInitCommon.c
new file mode 100644
index 0000000000..28032e5b24
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Library/PeiDxeSmmCpuPcieInitCommonLib/CpuPcieInitCommon.c
@@ -0,0 +1,445 @@
+/** @file
+ common library for CPU PCIe INIT PEI/DXE/SMM modules
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/PcieHelperLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/CpuPcieRpLib.h>
+#include <Register/CpuPcieRegs.h>
+#include <Library/CpuPcieInitCommon.h>
+#include <Library/CpuRegbarAccessLib.h>
+
+/**
+  Print registers value
+
+  @param[in] PrintMmioBase       Mmio base address
+  @param[in] PrintSize           Number of registers
+  @param[in] OffsetFromBase      Offset from mmio base address
+
+  @retval None
+**/
+VOID
+SaPrintRegisters (
+  IN  UINTN        PrintMmioBase,
+  IN  UINT32       PrintSize,
+  IN  UINT32       OffsetFromBase
+  )
+{
+  UINT32  Offset;
+  DEBUG ((DEBUG_VERBOSE, "       00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F"));
+  for (Offset = 0; Offset < PrintSize; Offset++) {
+    if ((Offset % 16) == 0) {
+      DEBUG ((DEBUG_VERBOSE, "\n %04X: ", (Offset + OffsetFromBase) & 0xFFF0));
+    }
+    DEBUG ((DEBUG_VERBOSE, "%02X ", MmioRead8 (PrintMmioBase + Offset)));
+  }
+  DEBUG ((DEBUG_VERBOSE, "\n"));
+}
+
+/**
+  Print registers value
+
+  @param[in] PrintPciSegmentBase Pci segment base address
+  @param[in] PrintSize           Number of registers
+  @param[in] OffsetFromBase      Offset from mmio base address
+
+  @retval None
+**/
+VOID
+SaPrintPciRegisters (
+  IN  UINT64       PrintPciSegmentBase,
+  IN  UINT32       PrintSize,
+  IN  UINT32       OffsetFromBase
+  )
+{
+  UINT32  Offset;
+  DEBUG ((DEBUG_VERBOSE, "       00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F"));
+  for (Offset = 0; Offset < PrintSize; Offset++) {
+    if ((Offset % 16) == 0) {
+      DEBUG ((DEBUG_VERBOSE, "\n %04X: ", (Offset + OffsetFromBase) & 0xFFF0));
+    }
+    DEBUG ((DEBUG_VERBOSE, "%02X ", PciSegmentRead8 (PrintPciSegmentBase + Offset)));
+  }
+  DEBUG ((DEBUG_VERBOSE, "\n"));
+}
+
+//
+// 2LM: PegPcie APIs using the Sideband Access Mechanism
+//
+/**
+  Reads an 8-bit PCI configuration register.
+
+  Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+  Other calls to this function will be routed to core PciSegmentRead8 function.
+
+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+
+  @return The 8-bit PCI configuration register specified by Address.
+**/
+UINT8
+EFIAPI
+PegPciSegmentRead8 (
+  IN UINT64                    Address
+  )
+{
+  return PciSegmentRead8 (Address);
+}
+
+/**
+  Writes an 8-bit PCI configuration register.
+
+  Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+  Other calls to this function will be routed to core PciSegmentWrite8 function.
+
+  @param  Address     Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  Value       The value to write.
+
+  @return The value written to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PegPciSegmentWrite8 (
+  IN UINT64                    Address,
+  IN UINT8                     Value
+  )
+{
+  return PciSegmentWrite8 (Address, Value);
+}
+
+/**
+  Reads a 16-bit PCI configuration register.
+
+  Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+  Other calls to this function will be routed to core PciSegmentRead16 function.
+
+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+
+  @return The 16-bit PCI configuration register specified by Address.
+**/
+UINT16
+EFIAPI
+PegPciSegmentRead16 (
+  IN UINT64                    Address
+  )
+{
+  return PciSegmentRead16 (Address);
+}
+
+/**
+  Writes a 16-bit PCI configuration register.
+
+  Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+  Other calls to this function will be routed to core PciSegmentWrite16 function.
+
+  @param  Address     Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  Value       The value to write.
+
+  @return The parameter of Value.
+**/
+UINT16
+EFIAPI
+PegPciSegmentWrite16 (
+  IN UINT64                    Address,
+  IN UINT16                     Value
+  )
+{
+  return PciSegmentWrite16 (Address, Value);
+}
+
+/**
+  Reads a 32-bit PCI configuration register.
+
+  Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+  Other calls to this function will be routed to core PciSegmentRead32 function.
+
+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+
+  @return The 32-bit PCI configuration register specified by Address.
+**/
+UINT32
+EFIAPI
+PegPciSegmentRead32 (
+  IN UINT64                    Address
+  )
+{
+  return PciSegmentRead32 (Address);
+}
+
+/**
+  Writes a 32-bit PCI configuration register.
+
+  Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+  Other calls to this function will be routed to core PciSegmentWrite32 function.
+
+  @param  Address     Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  Value       The value to write.
+
+  @return The parameter of Value.
+**/
+UINT32
+EFIAPI
+PegPciSegmentWrite32 (
+  IN UINT64                    Address,
+  IN UINT32                     Value
+  )
+{
+  return PciSegmentWrite32 (Address, Value);
+}
+
+/**
+  Performs a bitwise OR of a 16-bit PCI configuration register with a 16-bit value.
+
+  Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+  Other calls to this function will be routed to core PciSegmentOr16 function.
+
+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PegPciSegmentOr16 (
+  IN UINT64                    Address,
+  IN UINT16                    OrData
+  )
+{
+  return PciSegmentOr16 (Address, OrData);
+}
+
+/**
+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value.
+
+  Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+  Other calls to this function will be routed to core PciSegmentAnd32 function.
+
+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  AndData   The value to AND with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PegPciSegmentAnd16 (
+  IN UINT64                    Address,
+  IN UINT16                    AndData
+  )
+{
+  return PciSegmentAnd16 (Address, AndData);
+}
+
+/**
+  Performs a bitwise AND of a 8-bit PCI configuration register with a 8-bit value.
+
+  Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+  Other calls to this function will be routed to core PciSegmentAnd8 function.
+
+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  AndData   The value to AND with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PegPciSegmentAnd8 (
+  IN UINT64                    Address,
+  IN UINT8                     AndData
+  )
+{
+  return PciSegmentAnd8 (Address, AndData);
+}
+
+/**
+  Performs a bitwise OR of a 32-bit PCI configuration register with a 32-bit value.
+
+  Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+  Other calls to this function will be routed to core PciSegmentOr32 function.
+
+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PegPciSegmentOr32 (
+  IN UINT64                    Address,
+  IN UINT32                    OrData
+  )
+{
+  return PciSegmentOr32 (Address, OrData);
+}
+
+/**
+  Performs a bitwise OR of a 8-bit PCI configuration register with a 8-bit value.
+
+  Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+  Other calls to this function will be routed to core PciSegmentOr8 function.
+
+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PegPciSegmentOr8 (
+  IN UINT64                    Address,
+  IN UINT8                     OrData
+  )
+{
+  return PciSegmentOr8 (Address, OrData);
+}
+
+/**
+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value.
+
+  Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+  Other calls to this function will be routed to core PciSegmentAnd32 function.
+
+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  AndData   The value to AND with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PegPciSegmentAnd32 (
+  IN UINT64                    Address,
+  IN UINT32                    AndData
+  )
+{
+  return PciSegmentAnd32 (Address, AndData);
+}
+
+/**
+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value,
+  followed a  bitwise OR with another 32-bit value.
+
+  Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+  Other calls to this function will be routed to core PciSegmentAndThenOr32 function.
+
+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  AndData   The value to AND with the PCI configuration register.
+  @param  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PegPciSegmentAndThenOr32 (
+  IN UINT64                    Address,
+  IN UINT32                    AndData,
+  IN UINT32                    OrData
+  )
+{
+  return PciSegmentAndThenOr32 (Address, AndData, OrData);
+}
+
+
+/**
+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value,
+  followed a  bitwise OR with another 16-bit value.
+
+  Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+  Other calls to this function will be routed to core PciSegmentAndThenOr16 function.
+
+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  AndData   The value to AND with the PCI configuration register.
+  @param  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PegPciSegmentAndThenOr16 (
+  IN UINT64                    Address,
+  IN UINT16                    AndData,
+  IN UINT16                    OrData
+  )
+{
+  return PciSegmentAndThenOr16 (Address, AndData, OrData);
+}
+
+
+/**
+  Performs a bitwise AND of a 8-bit PCI configuration register with a 8-bit value,
+  followed a  bitwise OR with another 8-bit value.
+
+  Its a wrapper library function. This function uses side band access for PEG60 when 2LM mode is enabled.
+  Other calls to this function will be routed to core PciSegmentAndThenOr8 function.
+
+  @param  Address   Address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  AndData   The value to AND with the PCI configuration register.
+  @param  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PegPciSegmentAndThenOr8 (
+  IN UINT64                    Address,
+  IN UINT8                     AndData,
+  IN UINT8                     OrData
+  )
+{
+  return PciSegmentAndThenOr8 (Address, AndData, OrData);
+}
+
+
+/**
+  Find the Offset to a Capabilities ID
+  @param[in] Segment              Pci Segment Number
+  @param[in] Bus                  Pci Bus Number
+  @param[in] Device               Pci Device Number
+  @param[in] Function             Pci Function Number
+  @param[in] CapId                CAPID to search for
+
+  @retval 0                       CAPID not found
+  @retval Other                   CAPID found, Offset of desired CAPID
+**/
+UINT8
+PegPcieFindCapId (
+  IN UINT8   Segment,
+  IN UINT8   Bus,
+  IN UINT8   Device,
+  IN UINT8   Function,
+  IN UINT8   CapId
+  )
+{
+  return PcieFindCapId (Segment, Bus, Device, Function, CapId);
+}
+
+
+/**
+  Search and return the offset of desired Pci Express extended Capability ID
+  @param[in] Segment              Pci Segment Number
+  @param[in] Bus                  Pci Bus Number
+  @param[in] Device               Pci Device Number
+  @param[in] Function             Pci Function Number
+  @param[in] CapId                Extended CAPID to search for
+
+  @retval 0                       CAPID not found
+  @retval Other                   CAPID found, Offset of desired CAPID
+**/
+UINT16
+PegPcieFindExtendedCapId (
+  IN UINT8   Segment,
+  IN UINT8   Bus,
+  IN UINT8   Device,
+  IN UINT8   Function,
+  IN UINT16  CapId
+  )
+{
+  return PcieFindExtendedCapId (Segment, Bus, Device, Function, CapId);
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Library/PeiDxeSmmCpuPcieInitCommonLib/PeiDxeSmmCpuPcieInitCommonLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Library/PeiDxeSmmCpuPcieInitCommonLib/PeiDxeSmmCpuPcieInitCommonLib.inf
new file mode 100644
index 0000000000..2ad30ab7c9
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Library/PeiDxeSmmCpuPcieInitCommonLib/PeiDxeSmmCpuPcieInitCommonLib.inf
@@ -0,0 +1,33 @@
+## @file
+#  Component description file for the CpuPcieInitCommonLib
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = PeiDxeSmmCpuPcieInitCommonLib
+  FILE_GUID                      = 68992CB0-A3A5-4f73-9370-93A3559F84C8
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = CpuPcieInitCommonLib
+
+[Sources]
+  CpuPcieInitCommon.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  TigerlakeSiliconPkg/SiPkg.dec
+
+[LibraryClasses]
+  IoLib
+  DebugLib
+  PciSegmentLib
+  CpuPcieRpLib
+  CpuRegbarAccessLib
+  BasePcieHelperLib
+
+[Pcd]
+  gSiPkgTokenSpaceGuid.PcdCpuPcieEnable                  ## CONSUMES
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Library/PeiDxeSmmCpuPcieRpLib/CpuPcieRpLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Library/PeiDxeSmmCpuPcieRpLib/CpuPcieRpLib.c
new file mode 100644
index 0000000000..02cd482b55
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Library/PeiDxeSmmCpuPcieRpLib/CpuPcieRpLib.c
@@ -0,0 +1,48 @@
+/** @file
+  CPU PCIe root port library.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <PcieRegs.h>
+#include <Register/CpuPcieRegs.h>
+#include "CpuPcieInfo.h"
+#include <Library/CpuPcieInitCommon.h>
+#include <Library/PciLib.h>
+#include <IndustryStandard/Pci22.h>
+
+/**
+  Determines whether PCIe link is active
+
+  @param[in] RpBase    Root Port base address
+  @retval Link Active state
+**/
+BOOLEAN
+CpuPcieIsLinkActive (
+  UINT64  RpBase
+  )
+{
+  return !! (PegPciSegmentRead16 (RpBase + R_PCIE_LSTS) & B_PCIE_LSTS_LA);
+}
+
+/**
+  Get max PCIe link speed supported by the root port.
+
+  @param[in] RpBase    Root Port base address
+  @return    Max link speed
+**/
+UINT32
+CpuPcieGetMaxLinkSpeed (
+  UINT64 RpBase
+  )
+{
+  return PegPciSegmentRead32 (RpBase + R_PCIE_LCAP) & B_PCIE_LCAP_MLS;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Library/PeiDxeSmmCpuPcieRpLib/PeiDxeSmmCpuPcieRpLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Library/PeiDxeSmmCpuPcieRpLib/PeiDxeSmmCpuPcieRpLib.inf
new file mode 100644
index 0000000000..cea8bcbecd
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/Library/PeiDxeSmmCpuPcieRpLib/PeiDxeSmmCpuPcieRpLib.inf
@@ -0,0 +1,32 @@
+## @file
+# CPU PCIE root port Library.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmCpuPcieRpLib
+FILE_GUID = 00199A03-41F4-43c7-B6D5-5A3AA1EE78D0
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = CpuPcieRpLib
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PciLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Sources]
+CpuPcieRpLib.c
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/LibraryPrivate/DxeCpuPcieRpLib/DxeCpuPcieRpLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/LibraryPrivate/DxeCpuPcieRpLib/DxeCpuPcieRpLib.c
new file mode 100644
index 0000000000..48ef8165de
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/LibraryPrivate/DxeCpuPcieRpLib/DxeCpuPcieRpLib.c
@@ -0,0 +1,62 @@
+/** @file
+  The DXE CPU PCIE RP Library Implements After Memory PEIM
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Base.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Ppi/SiPolicy.h>
+#include <Library/HobLib.h>
+#include <Library/PciSegmentLib.h>
+#include <IndustryStandard/Pci22.h>
+#include <Protocol/SaPolicy.h>
+#include <Protocol/SaNvsArea.h>
+#include <Library/PcdLib.h>
+#include <Library/PciExpressHelpersLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <ConfigBlock/PcieDxeConfig.h>
+#include <Register/SaRegsHostBridge.h>
+
+/**
+Update CPU PCIE RP NVS AREA tables
+
+**/
+VOID
+UpdateCpuPcieNVS (
+  VOID
+  )
+{
+  EFI_STATUS                       Status;
+  PCIE_DXE_CONFIG                  *PcieDxeConfig;
+  SA_POLICY_PROTOCOL               *SaPolicy;
+  SYSTEM_AGENT_NVS_AREA_PROTOCOL   *SaNvsAreaProtocol;
+
+  DEBUG ((DEBUG_INFO, "Update Cpu Pcie NVS Area.\n"));
+
+  Status = gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID **) &SaPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *)SaPolicy, &gPcieDxeConfigGuid, (VOID *)&PcieDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gBS->LocateProtocol (&gSaNvsAreaProtocolGuid, NULL, (VOID **) &SaNvsAreaProtocol);
+  if (Status != EFI_SUCCESS) {
+    DEBUG ((DEBUG_ERROR, "Locate SA NVS Area failed.\n"));
+    return;
+  }
+
+  SaNvsAreaProtocol->Area->Peg0LtrEnable  = PcieDxeConfig->PegPwrOpt[0].LtrEnable;
+  SaNvsAreaProtocol->Area->Peg0ObffEnable = PcieDxeConfig->PegPwrOpt[0].ObffEnable;
+  SaNvsAreaProtocol->Area->Peg1LtrEnable  = PcieDxeConfig->PegPwrOpt[1].LtrEnable;
+  SaNvsAreaProtocol->Area->Peg1ObffEnable = PcieDxeConfig->PegPwrOpt[1].ObffEnable;
+  SaNvsAreaProtocol->Area->Peg2LtrEnable  = PcieDxeConfig->PegPwrOpt[2].LtrEnable;
+  SaNvsAreaProtocol->Area->Peg2ObffEnable = PcieDxeConfig->PegPwrOpt[2].ObffEnable;
+  SaNvsAreaProtocol->Area->Peg3LtrEnable  = PcieDxeConfig->PegPwrOpt[3].LtrEnable;
+  SaNvsAreaProtocol->Area->Peg3ObffEnable = PcieDxeConfig->PegPwrOpt[3].ObffEnable;
+  SaNvsAreaProtocol->Area->PegLtrMaxSnoopLatency = V_SA_LTR_MAX_SNOOP_LATENCY_VALUE;
+  SaNvsAreaProtocol->Area->PegLtrMaxNoSnoopLatency = V_SA_LTR_MAX_NON_SNOOP_LATENCY_VALUE;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/LibraryPrivate/DxeCpuPcieRpLib/DxeCpuPcieRpLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/LibraryPrivate/DxeCpuPcieRpLib/DxeCpuPcieRpLib.inf
new file mode 100644
index 0000000000..dc9b893be3
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/CpuPcieRp/LibraryPrivate/DxeCpuPcieRpLib/DxeCpuPcieRpLib.inf
@@ -0,0 +1,40 @@
+## @file
+#   The DXE CPU PCIE RP Library Implements After Memory PEIM
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeCpuPcieRpLib
+FILE_GUID = D563A22E-6A01-4EF7-84D1-78B6717E3402
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_DRIVER
+UEFI_SPECIFICATION_VERSION = 2.00
+LIBRARY_CLASS = DxeCpuPcieRpLib
+
+[LibraryClasses]
+IoLib
+BaseLib
+DebugLib
+BaseMemoryLib
+UefiBootServicesTableLib
+UefiLib
+HobLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Sources]
+DxeCpuPcieRpLib.c
+
+[Guids]
+gPcieDxeConfigGuid
+
+[Protocols]
+gSaPolicyProtocolGuid                  ## CONSUMES
+gSaNvsAreaProtocolGuid                 ## CONSUMES
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 15/40] TigerlakeSiliconPkg/IpBlock: Add Espi component
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (12 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 14/40] TigerlakeSiliconPkg/IpBlock: Add CpuPcieRp component Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 16/40] TigerlakeSiliconPkg/IpBlock: Add Gbe component Heng Luo
                   ` (24 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * IpBlock/Espi/Library

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/EspiLib.c            | 469 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/PeiDxeSmmEspiLib.inf |  38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 507 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/EspiLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/EspiLib.c
new file mode 100644
index 0000000000..2d1928ce18
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/EspiLib.c
@@ -0,0 +1,469 @@
+/** @file
+  This file contains routines for eSPI
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/EspiLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/TimerLib.h>
+#include <PchLimits.h>
+#include <Register/PchPcrRegs.h>
+#include <Register/PchRegsLpc.h>
+
+#define CHANNEL_RESET_TIMEOUT     100   ///< Channel reset timeout in us after which to report error
+#define SLAVE_CHANNELS_MAX        7     ///< Max number of channels
+
+//
+// eSPI Slave registers
+//
+#define R_ESPI_SLAVE_GENCAP               0x08      ///< General Capabilities and Configurations
+#define B_ESPI_SLAVE_GENCAP_SUPPCHAN      0xFF      ///< Channels supported bit mask
+#define R_ESPI_SLAVE_CHACAP_BASE          0x10      ///< Base address from which channel Cap and Conf registers start on slave
+#define S_ESPI_SLAVE_CHACAP_OFFSET        0x10      ///< Offset for each channel from base
+#define B_ESPI_SLAVE_CHACAP_CHEN          BIT0      ///< Slave Channel enable bit
+#define B_ESPI_SLAVE_CHACAP_CHRDY         BIT1      ///< Slave Channel ready bit
+
+/**
+  Checks if second slave capability is enabled
+
+  @retval TRUE      There's second slave
+  @retval FALSE     There's no second slave
+**/
+BOOLEAN
+IsEspiSecondSlaveSupported (
+  VOID
+  )
+{
+  return FALSE;
+}
+
+/**
+  Checks in slave General Capabilities register if it supports channel with requested number
+
+  @param[in]  SlaveId         Id of slave to check
+  @param[in]  ChannelNumber   Number of channel of which to check
+
+  @retval TRUE      Channel with requested number is supported by slave device
+  @retval FALSE     Channel with requested number is not supported by slave device
+**/
+BOOLEAN
+IsEspiSlaveChannelSupported (
+  UINT8   SlaveId,
+  UINT8   ChannelNumber
+  )
+{
+  UINT32  Data32;
+  UINT8   SupportedChannels;
+
+  PchEspiSlaveGetConfig (SlaveId, R_ESPI_SLAVE_GENCAP, &Data32);
+  SupportedChannels = (UINT8) (Data32 & B_ESPI_SLAVE_GENCAP_SUPPCHAN);
+
+  DEBUG ((DEBUG_INFO, "Slave %d supported channels 0x%4X\n", SlaveId, SupportedChannels));
+
+  if (ChannelNumber > SLAVE_CHANNELS_MAX || !(SupportedChannels & (BIT0 << ChannelNumber))) {
+    // Incorrect channel number was specified. Either exceeded max or Slave doesn't support that channel.
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+/**
+  Is eSPI enabled in strap.
+
+  @retval TRUE          Espi is enabled in strap
+  @retval FALSE         Espi is disabled in strap
+**/
+BOOLEAN
+IsEspiEnabled (
+  VOID
+  )
+{
+  return (PchPcrRead32 (PID_ESPISPI, R_ESPI_PCR_CFG_VAL) & B_ESPI_PCR_CFG_VAL_ESPI_EN) != 0;
+}
+
+/**
+  eSPI helper function to clear slave configuration register status
+
+  @retval EFI_SUCCESS Write to private config space succeed
+  @retval others      Read / Write failed
+**/
+STATIC
+VOID
+EspiClearScrs (
+  VOID
+  )
+{
+  PchPcrAndThenOr32 (
+    PID_ESPISPI,
+    R_ESPI_PCR_SLV_CFG_REG_CTL,
+    (UINT32) ~0,
+     B_ESPI_PCR_SLV_CFG_REG_CTL_SCRS
+     );
+}
+
+/**
+  eSPI helper function to poll slave configuration register enable for 0
+  and to check for slave configuration register status
+
+  @retval EFI_SUCCESS       Enable bit is zero and no error in status bits
+  @retval EFI_DEVICE_ERROR  Error in SCRS
+  @retval others            Read / Write to private config space failed
+**/
+STATIC
+EFI_STATUS
+EspiPollScreAndCheckScrs (
+  VOID
+  )
+{
+  UINT32     ScrStat;
+
+  do {
+    ScrStat = PchPcrRead32 (PID_ESPISPI, R_ESPI_PCR_SLV_CFG_REG_CTL);
+  } while ((ScrStat & B_ESPI_PCR_SLV_CFG_REG_CTL_SCRE) != 0);
+
+  ScrStat = (ScrStat & B_ESPI_PCR_SLV_CFG_REG_CTL_SCRS) >> N_ESPI_PCR_SLV_CFG_REG_CTL_SCRS;
+  if (ScrStat != V_ESPI_PCR_SLV_CFG_REG_CTL_SCRS_NOERR) {
+    DEBUG ((DEBUG_ERROR, "eSPI slave config register status (error) is %x \n", ScrStat));
+    return EFI_DEVICE_ERROR;
+  }
+  return EFI_SUCCESS;
+}
+
+typedef enum {
+  EspiSlaveOperationConfigRead,
+  EspiSlaveOperationConfigWrite,
+  EspiSlaveOperationStatusRead,
+  EspiSlaveOperationInBandReset
+} ESPI_SLAVE_OPERATION;
+
+/**
+  Helper library to do all the operations regards to eSPI slave
+
+  @param[in]      SlaveId         eSPI Slave ID
+  @param[in]      SlaveAddress    Slave address to be put in R_ESPI_PCR_SLV_CFG_REG_CTL[11:0]
+  @param[in]      SlaveOperation  Based on ESPI_SLAVE_OPERATION
+  @param[in,out]  Data
+
+  @retval EFI_SUCCESS           Operation succeed
+  @retval EFI_INVALID_PARAMETER Slave ID is not supported or SlaveId 1 is used in PCH_LP
+  @retval EFI_INVALID_PARAMETER Slave configuration register address exceed maximum allowed
+  @retval EFI_INVALID_PARAMETER Slave configuration register address is not DWord aligned
+  @retval EFI_ACCESS_DENIED     eSPI Slave write to address range 0 to 0x7FF has been locked
+  @retval EFI_DEVICE_ERROR      Error in SCRS during polling stage of operation
+**/
+STATIC
+EFI_STATUS
+EspiSlaveOperationHelper (
+  IN     UINT32               SlaveId,
+  IN     UINT32               SlaveAddress,
+  IN     ESPI_SLAVE_OPERATION SlaveOperation,
+  IN OUT UINT32               *Data
+  )
+{
+  EFI_STATUS  Status;
+  UINT32      Data32;
+
+  //
+  // Check the SlaveId is 0 or 1
+  //
+  if (SlaveId >= PCH_MAX_ESPI_SLAVES) {
+    DEBUG ((DEBUG_ERROR, "eSPI Slave ID of %d or more is not accepted \n", PCH_MAX_ESPI_SLAVES));
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Check if SlaveId 1 is used, it is not a PCH_LP
+  //
+  if (SlaveId == 1) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Check the address is not more then 0xFFF
+  //
+  if (SlaveAddress > B_ESPI_PCR_SLV_CFG_REG_CTL_SCRA) {
+    DEBUG ((DEBUG_ERROR, "eSPI Slave address must be less than 0x%x \n", (B_ESPI_PCR_SLV_CFG_REG_CTL_SCRA + 1)));
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Check the address is DWord aligned
+  //
+  if ((SlaveAddress & 0x3) != 0) {
+    DEBUG ((DEBUG_ERROR, "eSPI Slave address must be DWord aligned \n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Check if write is allowed
+  //
+  if ((SlaveOperation == EspiSlaveOperationConfigWrite) &&
+      (SlaveAddress <= 0x7FF)) {
+
+    //
+    // If the SLCRR is not set in corresponding slave, we will check the lock bit
+    //
+    Data32 = PchPcrRead32 (PID_ESPISPI, (UINT16) (R_ESPI_PCR_LNKERR_SLV0 + (SlaveId * S_ESPI_PCR_LNKERR_SLV0)));
+    if ((Data32 & B_ESPI_PCR_LNKERR_SLV0_SLCRR) == 0) {
+
+      Data32 = PchPcrRead32 (PID_ESPISPI, (UINT16) R_ESPI_PCR_SLV_CFG_REG_CTL);
+      if ((Data32 & B_ESPI_PCR_SLV_CFG_REG_CTL_SBLCL) != 0) {
+        DEBUG ((DEBUG_ERROR, "eSPI Slave write to address range 0 to 0x7FF has been locked \n"));
+        return EFI_ACCESS_DENIED;
+      }
+    }
+  }
+
+  //
+  // Input check done, now go through all the processes
+  //
+   EspiClearScrs ();
+
+  if (SlaveOperation == EspiSlaveOperationConfigWrite) {
+    PchPcrWrite32 (
+      PID_ESPISPI,
+      (UINT16) R_ESPI_PCR_SLV_CFG_REG_DATA,
+      *Data
+      );
+  }
+
+  PchPcrAndThenOr32 (
+    PID_ESPISPI,
+    (UINT16) R_ESPI_PCR_SLV_CFG_REG_CTL,
+    (UINT32) ~(B_ESPI_PCR_SLV_CFG_REG_CTL_SID | B_ESPI_PCR_SLV_CFG_REG_CTL_SCRT | B_ESPI_PCR_SLV_CFG_REG_CTL_SCRA),
+    (B_ESPI_PCR_SLV_CFG_REG_CTL_SCRE |
+     (SlaveId << N_ESPI_PCR_SLV_CFG_REG_CTL_SID) |
+     (((UINT32) SlaveOperation) << N_ESPI_PCR_SLV_CFG_REG_CTL_SCRT) |
+     SlaveAddress
+     )
+    );
+
+  Status = EspiPollScreAndCheckScrs ();
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  if ((SlaveOperation == EspiSlaveOperationConfigRead) || (SlaveOperation == EspiSlaveOperationStatusRead)) {
+    Data32 = PchPcrRead32 (
+               PID_ESPISPI,
+               (UINT16) R_ESPI_PCR_SLV_CFG_REG_DATA
+               );
+    if (SlaveOperation == EspiSlaveOperationStatusRead) {
+      *Data = Data32 & 0xFFFF;
+    } else {
+      *Data = Data32;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Get configuration from eSPI slave
+
+  @param[in]  SlaveId       eSPI slave ID
+  @param[in]  SlaveAddress  Slave Configuration Register Address
+  @param[out] OutData       Configuration data read
+
+  @retval EFI_SUCCESS           Operation succeed
+  @retval EFI_INVALID_PARAMETER Slave ID is not supported
+  @retval EFI_INVALID_PARAMETER Slave ID is not supported or SlaveId 1 is used in PCH_LP
+  @retval EFI_INVALID_PARAMETER Slave configuration register address exceed maximum allowed
+  @retval EFI_INVALID_PARAMETER Slave configuration register address is not DWord aligned
+  @retval EFI_DEVICE_ERROR      Error in SCRS during polling stage of operation
+**/
+EFI_STATUS
+PchEspiSlaveGetConfig (
+  IN  UINT32 SlaveId,
+  IN  UINT32 SlaveAddress,
+  OUT UINT32 *OutData
+  )
+{
+  //
+  // 1. Clear status from previous transaction by writing 111b to status in SCRS, PCR[eSPI] + 4000h [30:28]
+  // 2. Program SLV_CFG_REG_CTL with the right value (Bit[31]=01, Bit [20:19]=<SlvID>, Bit [17:16] = 00b, Bit[11:0] = <addr_xxx>.
+  // 3. Poll the SCRE (PCR[eSPI] +4000h [31]) to be set back to 0
+  // 4. Check the transaction status in SCRS (bits [30:28])
+  // 5. Read SLV_CFG_REG_DATA.
+  //
+  return EspiSlaveOperationHelper (SlaveId, SlaveAddress, EspiSlaveOperationConfigRead, OutData);
+}
+
+/**
+  Set eSPI slave configuration
+
+  Note: A Set_Configuration must always be followed by a Get_Configuration in order to ensure
+  that the internal state of the eSPI-MC is consistent with the Slave's register settings.
+
+  @param[in]  SlaveId       eSPI slave ID
+  @param[in]  SlaveAddress  Slave Configuration Register Address
+  @param[in]  InData        Configuration data to write
+
+  @retval EFI_SUCCESS           Operation succeed
+  @retval EFI_INVALID_PARAMETER Slave ID is not supported or SlaveId 1 is used in PCH_LP
+  @retval EFI_INVALID_PARAMETER Slave configuration register address exceed maximum allowed
+  @retval EFI_INVALID_PARAMETER Slave configuration register address is not DWord aligned
+  @retval EFI_ACCESS_DENIED     eSPI Slave write to address range 0 to 0x7FF has been locked
+  @retval EFI_DEVICE_ERROR      Error in SCRS during polling stage of operation
+**/
+EFI_STATUS
+PchEspiSlaveSetConfig (
+  IN  UINT32 SlaveId,
+  IN  UINT32 SlaveAddress,
+  IN  UINT32 InData
+  )
+{
+  EFI_STATUS  Status;
+  UINT32      Data32;
+
+  //
+  // 1. Clear status from previous transaction by writing 111b to status in SCRS, PCR[eSPI] + 4000h [30:28]
+  // 2. Program SLV_CFG_REG_DATA with the write value.
+  // 3. Program SLV_CFG_REG_CTL with the right value (Bit[31]=01, Bit [20:19]=<SlvID>, Bit [17:16] = 01b, Bit[11:0] = <addr_xxx>.
+  // 4. Poll the SCRE (PCR[eSPI] +4000h [31]) to be set back to 0
+  // 5. Check the transaction status in SCRS (bits [30:28])
+  //
+  Status = EspiSlaveOperationHelper (SlaveId, SlaveAddress, EspiSlaveOperationConfigWrite, &InData);
+  PchEspiSlaveGetConfig (SlaveId, SlaveAddress, &Data32);
+  return Status;
+}
+
+/**
+  Get status from eSPI slave
+
+  @param[in]  SlaveId       eSPI slave ID
+  @param[out] OutData       Configuration data read
+
+  @retval EFI_SUCCESS           Operation succeed
+  @retval EFI_INVALID_PARAMETER Slave ID is not supported or SlaveId 1 is used in PCH_LP
+  @retval EFI_DEVICE_ERROR      Error in SCRS during polling stage of operation
+**/
+EFI_STATUS
+PchEspiSlaveGetStatus (
+  IN  UINT32 SlaveId,
+  OUT UINT16 *OutData
+  )
+{
+  EFI_STATUS  Status;
+  UINT32      TempOutData;
+
+  TempOutData = 0;
+
+  //
+  // 1. Clear status from previous transaction by writing 111b to status in SCRS, PCR[eSPI] + 4000h [30:28]
+  // 2. Program SLV_CFG_REG_CTL with the right value (Bit[31]=01, Bit [20:19]=<SlvID>, Bit [17:16] = 10b, Bit[11:0] = <addr_xxx>.
+  // 3. Poll the SCRE (PCR[eSPI] +4000h [31]) to be set back to 0
+  // 4. Check the transaction status in SCRS (bits [30:28])
+  // 5. Read SLV_CFG_REG_DATA [15:0].
+  //
+  Status = EspiSlaveOperationHelper (SlaveId, 0, EspiSlaveOperationStatusRead, &TempOutData);
+  *OutData = (UINT16) TempOutData;
+
+  return Status;
+}
+
+/**
+  eSPI slave in-band reset
+
+  @param[in]  SlaveId           eSPI slave ID
+
+  @retval EFI_SUCCESS           Operation succeed
+  @retval EFI_INVALID_PARAMETER Slave ID is not supported or SlaveId 1 is used in PCH_LP
+  @retval EFI_DEVICE_ERROR      Error in SCRS during polling stage of operation
+**/
+EFI_STATUS
+PchEspiSlaveInBandReset (
+  IN  UINT32 SlaveId
+  )
+{
+  //
+  // 1. Clear status from previous transaction by writing 111b to status in SCRS, PCR[eSPI] + 4000h [30:28]
+  // 2. Program SLV_CFG_REG_CTL with the right value (Bit[31]=01, Bit [20:19]=<SlvID>, Bit [17:16] = 11b).
+  // 3. Poll the SCRE (PCR[eSPI] +4000h [31]) to be set back to 0
+  // 4. Check the transaction status in SCRS (bits [30:28])
+  //
+  return EspiSlaveOperationHelper (SlaveId, 0, EspiSlaveOperationInBandReset, NULL);
+}
+
+/**
+  eSPI Slave channel reset helper function
+
+  @param[in]  SlaveId           eSPI slave ID
+  @param[in]  ChannelNumber     Number of channel to reset
+
+  @retval     EFI_SUCCESS       Operation succeeded
+  @retval     EFI_UNSUPPORTED   Slave doesn't support that channel or invalid number specified
+  @retval     EFI_TIMEOUT       Operation has timeouted
+**/
+EFI_STATUS
+PchEspiSlaveChannelReset (
+  IN  UINT8   SlaveId,
+  IN  UINT8   ChannelNumber
+  )
+{
+  UINT8       Timeout;
+  UINT32      Data32;
+  UINT32      SlaveChannelAddress;
+  BOOLEAN     SlaveBmeSet;
+
+  DEBUG ((DEBUG_INFO, "eSPI slave %d channel %d reset\n", SlaveId, ChannelNumber));
+
+  Timeout = CHANNEL_RESET_TIMEOUT;
+  SlaveBmeSet = FALSE;
+
+  if (!IsEspiSlaveChannelSupported (SlaveId, ChannelNumber)) {
+    // Incorrect channel number was specified. Either exceeded max or Slave doesn't support that channel.
+    DEBUG ((DEBUG_ERROR, "Channel %d is not valid channel number for slave %d!\n", ChannelNumber, SlaveId));
+    return EFI_UNSUPPORTED;
+  }
+
+  // Calculating slave channel address
+  SlaveChannelAddress = R_ESPI_SLAVE_CHACAP_BASE + (S_ESPI_SLAVE_CHACAP_OFFSET * ChannelNumber);
+
+  // If we're resetting Peripheral Channel then we need to disable Bus Mastering first and reenable after reset
+  if (ChannelNumber == 0) {
+    PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data32);
+    if ((Data32 & B_ESPI_SLAVE_BME) != 0) {
+      Data32 &= ~(B_ESPI_SLAVE_BME);
+      PchEspiSlaveSetConfig (SlaveId, SlaveChannelAddress, Data32);
+      SlaveBmeSet = TRUE;
+    }
+  }
+
+  // Disable channel
+  PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data32);
+  Data32 &= ~(B_ESPI_SLAVE_CHACAP_CHEN);
+  PchEspiSlaveSetConfig (SlaveId, SlaveChannelAddress, Data32);
+
+  // Enable channel
+  PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data32);
+  Data32 |= B_ESPI_SLAVE_CHACAP_CHEN;
+  PchEspiSlaveSetConfig (SlaveId, SlaveChannelAddress, Data32);
+
+  DEBUG ((DEBUG_INFO, "Waiting for Channel Ready bit\n"));
+  // Wait until channel is ready by polling Channel Ready bit
+  while (((Data32 & B_ESPI_SLAVE_CHACAP_CHRDY) == 0) && (Timeout > 0)) {
+    PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data32);
+    MicroSecondDelay (1);
+    --Timeout;
+  }
+
+  if (Timeout == 0) {
+    // The waiting for channel to be ready has timed out
+    DEBUG ((DEBUG_ERROR, "The operation of channel %d reset for slave %d has timed out!\n", ChannelNumber, SlaveId));
+    return EFI_TIMEOUT;
+  }
+
+  if (ChannelNumber == 0 && SlaveBmeSet) {
+    PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data32);
+    Data32 |= B_ESPI_SLAVE_BME;
+    PchEspiSlaveSetConfig (SlaveId, SlaveChannelAddress, Data32);
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/PeiDxeSmmEspiLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/PeiDxeSmmEspiLib.inf
new file mode 100644
index 0000000000..440051432f
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/PeiDxeSmmEspiLib.inf
@@ -0,0 +1,38 @@
+## @file
+# Component description file for the PeiDxeSmmPchEspiLib
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmEspiLib
+FILE_GUID = 7F25F990-7989-4413-B414-1EDE557E9389
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = EspiLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PchPcrLib
+TimerLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+EspiLib.c
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 16/40] TigerlakeSiliconPkg/IpBlock: Add Gbe component
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (13 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 15/40] TigerlakeSiliconPkg/IpBlock: Add Espi component Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 17/40] TigerlakeSiliconPkg/IpBlock: Add Gpio component Heng Luo
                   ` (23 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * IpBlock/Gbe/IncludePrivate
  * IpBlock/Gbe/Library
  * IpBlock/Gbe/LibraryPrivate

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/IncludePrivate/Library/GbeMdiLib.h                       | 324 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/IncludePrivate/Register/GbeRegs.h                        |  68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/Library/PeiDxeSmmGbeLib/GbeLib.c                         | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/Library/PeiDxeSmmGbeLib/PeiDxeSmmGbeLib.inf              |  43 +++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/LibraryPrivate/PeiDxeSmmGbeMdiLib/GbeMdiLib.c            | 388 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/LibraryPrivate/PeiDxeSmmGbeMdiLib/PeiDxeSmmGbeMdiLib.inf |  34 ++++++++++++++++++++++++++++++++++
 6 files changed, 978 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/IncludePrivate/Library/GbeMdiLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/IncludePrivate/Library/GbeMdiLib.h
new file mode 100644
index 0000000000..b8274ed3dc
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/IncludePrivate/Library/GbeMdiLib.h
@@ -0,0 +1,324 @@
+/** @file
+  Header file for GbeMdiLib.
+
+  Conventions:
+
+  - Prefixes:
+    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 sizes
+    Definitions beginning with "N_" are the bit position
+  - In general, PCH registers are denoted by "_PCH_" in register names
+  - Registers / bits that are different between PCH generations are denoted by
+    "_PCH_[generation_name]_" in register/bit names.
+  - Registers / bits that are specific to PCH-H denoted by "_H_" in register/bit names.
+    Registers / bits that are specific to PCH-LP denoted by "_LP_" in register/bit names.
+    e.g., "_PCH_LP_"
+    Registers / bits names without or _LP_ apply for LP.
+  - Registers / bits that are different between SKUs are denoted by "_[SKU_name]"
+    at the end of the register/bit names
+  - Registers / bits of new devices introduced in a PCH generation will be just named
+    as "_PCH_" without [generation_name] inserted.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _GBE_MDI_LIB_H_
+#define _GBE_MDI_LIB_H_
+
+//
+// Maximum loop time for GbE status check
+// 4000 * 50 = 200 mSec in total
+//
+#define GBE_MAX_LOOP_TIME       4000
+#define GBE_ACQUIRE_MDIO_DELAY  50
+#define GBE_MDI_SET_PAGE_DELAY  4000 // 4 mSec delay after setting page
+
+//
+// LAN PHY MDI settings
+//
+// MDI Control Register Bits
+// 31:30 Reserved
+//       This field is reserved and returns 0.
+// 29    Interrupt Enable.
+//       When this bit is set to 1 by software, it causes the device to assert
+//       an interrupt indicating the end of an MDI cycle.
+// 28    Ready.
+//       Set to 1 by the device at the end of MDI transaction (i.e., indicates a Read or
+//       Write has been completed. It should be reset to 0 by software at the same time the
+//       command is written.
+// 27:26 Opcode
+//       For an MDI write, the opcode equals 01b, and for MDI read, 10b. 00b and
+//       11b are reserved and should not be used.
+// 25:21 PHYAdd
+//       PHY Address
+// 20:16 RegAdd
+//       PHY Register Address
+// 15:0  Data
+
+#define B_PHY_MDI_READY                BIT28
+#define B_PHY_MDI_READ                 BIT27
+#define B_PHY_MDI_WRITE                BIT26
+//
+//      PHY SPECIFIC registers
+//
+#define B_PHY_MDI_PHY_ADDRESS_02       BIT22
+//
+//      PHY GENERAL registers
+//      Registers 0 to 15 are defined by the specification
+//      Registers 16 to 31 are left available to the vendor
+//
+#define B_PHY_MDI_PHY_ADDRESS_01       BIT21
+#define B_PHY_MDI_PHY_ADDRESS_MASK    (BIT25 | BIT24 | BIT23 | BIT22 | BIT21)
+//
+//  PHY Identifier Register 2
+//  Bits [15:10] - PHY ID Number   - The PHY identifier composed of bits 3 through 18
+//                                   of the Organizationally Unique Identifier (OUI)
+//  Bits [9:4]   - Device Model Number
+//  Bits [3:0]   - Device Revision Number
+//
+#define R_PHY_MDI_GENEREAL_REGISTER_03_PHY_IDENTIFIER_2  0x00030000
+
+#define MDI_REG_SHIFT(x)                              (x << 16)
+#define B_PHY_MDI_PHY_REGISTER_MASK                   (BIT20 | BIT19 | BIT18 | BIT17 | BIT16)
+#define R_PHY_MDI_PHY_REG_SET_ADDRESS                 0x00110000 // Used after new page setting
+#define R_PHY_MDI_PHY_REG_DATA_READ_WRITE             0x00120000
+#define R_PHY_MDI_PHY_REG_SET_PAGE                    0x001F0000
+
+//
+// LAN PHY MDI registers and bits
+//
+
+//
+// Page 769 Port Control Registers
+// 6020h (769 * 32)
+//
+#define PHY_MDI_PAGE_769_PORT_CONTROL_REGISTERS        769
+//
+// Custom Mode Control PHY Address 01, Page 769, Register 16
+//
+#define R_PHY_MDI_PAGE_769_REGISETER_16_CMC            0x0010
+//
+// Custom Mode Control
+// Page 769, Register 16, BIT 10
+// 0 - normal MDIO frequency access
+// 1 - reduced MDIO frequency access (slow mdio)
+//     required for read during cable disconnect
+//
+#define B_PHY_MDI_PAGE_769_REGISETER_16_CMC_MDIO_FREQ_ACCESS        BIT10
+//
+//  Port General Configuration PHY Address 01, Page 769, Register 17
+//
+#define R_PHY_MDI_PAGE_769_REGISETER_17_PGC            0x0011
+//
+// Page 769, Register 17, BIT 4
+// Enables host wake up
+//
+#define B_PHY_MDI_PAGE_769_REGISETER_17_PGC_HOST_WAKE_UP            BIT4
+//
+// Page 769, Register 17, BIT 2
+// Globally enable the MAC power down feature while the
+// GbE supports WoL. When set to 1b,
+// pages 800 and 801 are enabled for
+// configuration and Host_WU_Active is not blocked for writes.
+//
+#define B_PHY_MDI_PAGE_769_REGISETER_17_PGC_MACPD_ENABLE            BIT2
+
+//
+// Page 800 Wake Up Registers
+// 6400h (800 * 32)
+//
+#define PHY_MDI_PAGE_800_WAKE_UP_REGISTERS             800
+//
+// Wake Up Control - WUC PHY Address 01, Page 800, Register 1
+// 1h (Register 1)
+//
+#define R_PHY_MDI_PAGE_800_REGISETER_1_WUC             0x0001
+//
+// Wake Up Control - (WUC)
+// Page 800, Register 1, BIT 0
+// Advance Power Management Enable (APME)
+// If set to 1b, APM wake up is enabled.
+//
+#define B_PHY_MDI_PAGE_800_REGISETER_1_WUC_APME                     BIT0
+//
+// Receive Address Low - RAL PHY Address 01, Page 800, Register 16
+// 10h (Register 16)
+//
+#define R_PHY_MDI_PAGE_800_REGISETER_16_RAL0           0x0010
+//
+// Receive Address Low - RAL PHY Address 01, Page 800, Register 17
+// 11h (Register 17)
+//
+#define R_PHY_MDI_PAGE_800_REGISETER_17_RAL1           0x0011
+//
+// Receive Address High - RAH PHY Address 01, Page 800, Register 18
+// 12h (Register 18)
+//
+#define R_PHY_MDI_PAGE_800_REGISETER_18_RAH0           0x0012
+//
+// Receive Address High - RAH PHY Address 01, Page 800, Register 19
+// 13h (Register 19)
+//
+#define R_PHY_MDI_PAGE_800_REGISETER_19_RAH1           0x0013
+//
+// Setting AV (BIT15 RAH is divided on two registers)
+// RAH Register 19, Page 800, BIT 31
+//
+// Address valid (AV)
+// When this bit is set, the relevant RAL and RAH are valid
+//
+#define B_PHY_MDI_PAGE_800_REGISETER_19_RAH1_ADDRESS_VALID          BIT15
+//
+// Page 803 Host WoL Packet
+// 6460h (803 * 32)
+//
+#define PHY_MDI_PAGE_803_HOST_WOL_PACKET               803
+//
+// Host WoL Packet Clear - HWPC PHY Address 01, Page 803, Register 66
+//
+#define R_PHY_MDI_PAGE_803_REGISETER_66_HWPC           0x0042
+
+
+/**
+  Change Extended Device Control Register BIT 11 to 1 which
+  forces the interface between the MAC and the Phy to be on SMBus.
+  Cleared on the assertion of PCI reset.
+
+  @param [in]  GbeBar   GbE MMIO space
+
+**/
+VOID
+GbeMdiForceMACtoSMB (
+  IN      UINT32  GbeBar
+  );
+
+/**
+  Test for MDIO operation complete.
+
+  @param [in]  GbeBar   GbE MMIO space
+
+  @retval EFI_SUCCESS
+  @retval EFI_TIMEOUT
+**/
+EFI_STATUS
+GbeMdiWaitReady (
+  IN      UINT32  GbeBar
+  );
+
+/**
+  Acquire MDIO software semaphore.
+
+  1. Ensure that MBARA offset F00h [5] = 1b
+  2. Poll MBARA offset F00h [5] up to 200ms
+
+  @param [in] GbeBar   GbE MMIO space
+
+  @retval EFI_SUCCESS
+  @retval EFI_TIMEOUT
+**/
+EFI_STATUS
+GbeMdiAcquireMdio (
+  IN      UINT32  GbeBar
+  );
+
+/**
+  Release MDIO software semaphore by clearing MBARA offset F00h [5]
+
+  @param [in]  GbeBar   GbE MMIO space
+**/
+VOID
+GbeMdiReleaseMdio (
+  IN      UINT32  GbeBar
+  );
+
+/**
+  Sets page on MDI
+  Page setting is attempted twice.
+  If first attempt failes MAC and the Phy are force to be on SMBus
+
+  @param [in]  GbeBar  GbE MMIO space
+  @param [in]  Data    Value to write in lower 16bits.
+
+  @retval EFI_SUCCESS       Page setting was successfull
+  @retval EFI_DEVICE_ERROR  Returned if both attermps of setting page failed
+**/
+EFI_STATUS
+GbeMdiSetPage (
+  IN      UINT32  GbeBar,
+  IN      UINT32  Page
+  );
+
+/**
+  Sets Register in current page.
+
+  @param [in]  GbeBar      GbE MMIO space
+  @param [in]  register    Register number
+
+  @return EFI_STATUS
+**/
+EFI_STATUS
+GbeMdiSetRegister (
+  IN      UINT32  GbeBar,
+  IN      UINT32  Register
+  );
+
+
+/**
+  Perform MDI read.
+
+  @param [in]  GbeBar       GbE MMIO space
+  @param [in]  PhyAddress   Phy Address General - 02 or Specific - 01
+  @param [in]  PhyRegister  Phy Register
+  @param [out] ReadData     Return Value
+
+  @retval EFI_SUCCESS            Based on response from GbeMdiWaitReady
+  @retval EFI_TIMEOUT            Based on response from GbeMdiWaitReady
+  @retval EFI_INVALID_PARAMETER  If Phy Address or Register validaton failed
+**/
+EFI_STATUS
+GbeMdiRead (
+  IN      UINT32  GbeBar,
+  IN      UINT32  PhyAddress,
+  IN      UINT32  PhyRegister,
+  OUT     UINT16  *ReadData
+  );
+
+/**
+  Perform MDI write.
+
+  @param [in]  GbeBar       GbE MMIO space
+  @param [in]  PhyAddress   Phy Address General - 02 or Specific - 01
+  @param [in]  PhyRegister  Phy Register
+  @param [in]  WriteData    Value to write in lower 16bits.
+
+  @retval EFI_SUCCESS            Based on response from GbeMdiWaitReady
+  @retval EFI_TIMEOUT            Based on response from GbeMdiWaitReady
+  @retval EFI_INVALID_PARAMETER  If Phy Address or Register validaton failed
+**/
+EFI_STATUS
+GbeMdiWrite (
+  IN      UINT32  GbeBar,
+  IN      UINT32  PhyAddress,
+  IN      UINT32  PhyRegister,
+  IN      UINT32  WriteData
+  );
+
+/**
+  Gets Phy Revision and Model Number
+  from PHY IDENTIFIER register 2 (offset 3)
+
+  @param [in]  GbeBar           GbE MMIO space
+  @param [out] LanPhyRevision   Return Value
+
+  @return EFI_STATUS
+  @return EFI_INVALID_PARAMETER When GbeBar is incorrect
+**/
+EFI_STATUS
+GbeMdiGetLanPhyRevision (
+  IN      UINT32  GbeBar,
+  OUT     UINT16  *LanPhyRevision
+  );
+
+#endif // _GBE_MDI_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/IncludePrivate/Register/GbeRegs.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/IncludePrivate/Register/GbeRegs.h
new file mode 100644
index 0000000000..307f1e159e
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/IncludePrivate/Register/GbeRegs.h
@@ -0,0 +1,68 @@
+/** @file
+  Register names for GbE device
+
+  Conventions:
+
+  - Register definition format:
+    Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpace_RegisterName
+  - Prefix:
+    Definitions beginning with "R_" are registers
+    Definitions beginning with "B_" are bits within registers
+    Definitions beginning with "V_" are meaningful values within the bits
+    Definitions beginning with "S_" are register size
+    Definitions beginning with "N_" are the bit position
+  - [GenerationName]:
+    Three letter acronym of the generation is used (e.g. SKL,KBL,CNL etc.).
+    Register name without GenerationName applies to all generations.
+  - [ComponentName]:
+    This field indicates the component name that the register belongs to (e.g. PCH, SA etc.)
+    Register name without ComponentName applies to all components.
+    Register that is specific to -LP denoted by "_PCH_LP_" in component name.
+  - SubsystemName:
+    This field indicates the subsystem name of the component that the register belongs to
+    (e.g. PCIE, USB, SATA, GPIO, PMC etc.).
+  - RegisterSpace:
+    MEM - MMIO space register of subsystem.
+    IO  - IO space register of subsystem.
+    PCR - Private configuration register of subsystem.
+    CFG - PCI configuration space register of subsystem.
+  - RegisterName:
+    Full register name.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _GBE_REGS_H_
+#define _GBE_REGS_H_
+
+#define R_GBE_CFG_MBARA               0x10
+#define N_GBE_CFG_MBARA_ALIGN         17
+#define R_GBE_CFG_PMCS                0xCC
+#define B_GBE_CFG_PMCS_PS             (BIT1 | BIT0)
+#define V_GBE_CFG_PMCS_PS0            0x00
+//
+// Gigabit Ethernet LAN Capabilities and Status Registers (Memory space)
+//
+#define R_GBE_MEM_CSR_CTRL                    0
+//
+// LANPHYPC:
+// Connects to the LCD DEVICE_OFF# signal in the
+// LAN Connected Device
+//
+#define B_GBE_MEM_CSR_CTRL_LANPHYPC_OVERRIDE  BIT16 // When set to 1 SW driver has the ability to control the LANPHYPC pin value.
+#define B_GBE_MEM_CSR_CTRL_LANPHYPC_VAL       BIT17 // When set to 1 this bit will define the value of the LANPHYPC pin.
+#define R_GBE_MEM_CSR_CTRL_EXT             0x0018
+#define B_GBE_MEM_CSR_CTRL_EXT_LPCD        BIT2  //LCD Power Cycle Done (LPCD). This bit indicates whether LCD power cycle is done
+                                                 //- the bit is set 50/100mSec after LANPHYPC pin assertion.
+#define B_GBE_MEM_CSR_CTRL_EXT_FORCE_SMB   BIT11
+#define R_GBE_MEM_CSR_MDIC                 0x0020
+#define B_GBE_MEM_CSR_MDIC_RB              BIT28
+#define R_GBE_MEM_CSR_EXTCNF_CTRL          0x0F00
+#define B_GBE_MEM_CSR_EXTCNF_CTRL_SWFLAG   BIT5
+#define R_GBE_MEM_CSR_RAL                  0x5400
+#define R_GBE_MEM_CSR_RAH                  0x5404
+#define B_GBE_MEM_CSR_RAH_RAH              0x0000FFFF
+#define R_GBE_MEM_CSR_WUC                  0x5800
+#define B_GBE_MEM_CSR_WUC_APME             BIT0
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/Library/PeiDxeSmmGbeLib/GbeLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/Library/PeiDxeSmmGbeLib/GbeLib.c
new file mode 100644
index 0000000000..3b51b9eb62
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/Library/PeiDxeSmmGbeLib/GbeLib.c
@@ -0,0 +1,121 @@
+/** @file
+  Gbe Library.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PmcPrivateLib.h>
+#include <Library/SpiAccessLib.h>
+#include <Library/GbeMdiLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Register/PchRegs.h>
+#include <Register/GbeRegs.h>
+#include <Library/PchPciBdfLib.h>
+
+/**
+  Check whether GbE region is valid
+  Check SPI region directly since GbE might be disabled in SW.
+
+  @retval TRUE                    Gbe Region is valid
+  @retval FALSE                   Gbe Region is invalid
+**/
+BOOLEAN
+IsGbeRegionValid (
+  VOID
+  )
+{
+  return SpiIsGbeRegionValid ();
+}
+
+/**
+  Check whether GBE controller is enabled in the platform.
+
+  @retval TRUE                    GbE is enabled
+  @retval FALSE                   GbE is disabled
+**/
+BOOLEAN
+IsGbePresent (
+  VOID
+  )
+{
+  //
+  // Check PCH Support
+  //
+  if (!PchIsGbeSupported ()) {
+    return FALSE;
+  }
+  //
+  // Check PMC strap/fuse
+  //
+  if (!PmcIsGbeSupported ()) {
+    return FALSE;
+  }
+  //
+  // Check GbE NVM
+  //
+  if (IsGbeRegionValid () == FALSE) {
+    return FALSE;
+  }
+  return TRUE;
+}
+
+/**
+  Verifies Gigabit Ethernet PCI Class Code
+
+  @param [in]  GbePciCfgBase      GbE PCI Config Space Address
+
+  @retval TRUE                    GbE Class Code match
+  @retval FALSE                   GbE Class Code does not match
+**/
+BOOLEAN
+STATIC
+GbeCheckClassCode (
+  UINT64 GbePciCfgBase
+  )
+{
+  UINT8 BaseCode;
+  UINT8 SubClassCode;
+
+  SubClassCode  = PciSegmentRead8 (GbePciCfgBase + PCI_CLASSCODE_OFFSET + 1);
+  BaseCode      = PciSegmentRead8 (GbePciCfgBase + PCI_CLASSCODE_OFFSET + 2);
+
+  if ((BaseCode != PCI_CLASS_NETWORK) || (SubClassCode != PCI_CLASS_NETWORK_ETHERNET)) {
+    DEBUG ((DEBUG_ERROR, "GbeCheckClassCode : BaseCode(0x%x) or ClassCode(0x%x) is not supported\n", BaseCode, SubClassCode));
+    ASSERT (FALSE);
+    return FALSE;
+  }
+  return TRUE;
+}
+
+/**
+  Checks if Gbe is Enabled or Disabled
+
+  @retval  BOOLEAN    TRUE if device is enabled, FALSE otherwise.
+**/
+BOOLEAN
+IsGbeEnabled (
+  VOID
+  )
+{
+  UINT64  GbePciBase;
+
+  GbePciBase = GbePciCfgBase ();
+
+  if (PciSegmentRead32 (GbePciBase) != 0xFFFFFFFF) {
+    return GbeCheckClassCode (GbePciBase);
+  }
+
+  return FALSE;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/Library/PeiDxeSmmGbeLib/PeiDxeSmmGbeLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/Library/PeiDxeSmmGbeLib/PeiDxeSmmGbeLib.inf
new file mode 100644
index 0000000000..4fef1288af
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/Library/PeiDxeSmmGbeLib/PeiDxeSmmGbeLib.inf
@@ -0,0 +1,43 @@
+## @file
+# Gbe Library.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmGbeLib
+FILE_GUID = FC022ED0-6EB3-43E1-A740-0BA27CBBD010
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = GbeLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PciSegmentLib
+PchInfoLib
+PchPcrLib
+PchCycleDecodingLib
+PmcPrivateLib
+SpiAccessLib
+GbeMdiLib
+PchPciBdfLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+GbeLib.c
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/LibraryPrivate/PeiDxeSmmGbeMdiLib/GbeMdiLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/LibraryPrivate/PeiDxeSmmGbeMdiLib/GbeMdiLib.c
new file mode 100644
index 0000000000..7917474406
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/LibraryPrivate/PeiDxeSmmGbeMdiLib/GbeMdiLib.c
@@ -0,0 +1,388 @@
+/** @file
+  Gbe MDI Library.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/TimerLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/GbeMdiLib.h>
+#include <Register/GbeRegs.h>
+
+
+/**
+  Validates both Phy Address and Regster.
+
+  @param [in]  PhyAddress
+  @param [in]  PhyRegister
+
+  @retval BOOLEAN   TRUE  Validation passed
+                    FALSE If the data is not within its range
+
+**/
+BOOLEAN
+IsPhyAddressRegisterValid (
+  IN      UINT32  PhyAddress,
+  IN      UINT32  PhyRegister
+  )
+{
+  if (((PhyAddress & (~B_PHY_MDI_PHY_ADDRESS_MASK)) != 0) || ((PhyRegister & (~B_PHY_MDI_PHY_REGISTER_MASK)) != 0)) {
+    DEBUG ((DEBUG_ERROR, "IsPhyAddressRegisterValid validation failed! PhyAddress: 0x%08X PhyRegister: 0x%08X \n", PhyAddress, PhyRegister));
+    return FALSE;
+  }
+  return TRUE;
+}
+
+/**
+  Change Extended Device Control Register BIT 11 to 1 which
+  forces the interface between the MAC and the Phy to be on SMBus.
+  Cleared on the assertion of PCI reset.
+
+  @param [in]  GbeBar   GbE MMIO space
+
+**/
+VOID
+GbeMdiForceMacToSmb (
+  IN      UINT32  GbeBar
+  )
+{
+  MmioOr32 (GbeBar + R_GBE_MEM_CSR_CTRL_EXT, B_GBE_MEM_CSR_CTRL_EXT_FORCE_SMB);
+}
+
+/**
+  Test for MDIO operation complete.
+
+  @param [in]  GbeBar   GbE MMIO space
+
+  @retval EFI_SUCCESS
+  @retval EFI_TIMEOUT
+**/
+EFI_STATUS
+GbeMdiWaitReady (
+  IN      UINT32  GbeBar
+  )
+{
+  UINT32  Count;
+
+  for (Count = 0; Count < GBE_MAX_LOOP_TIME; ++Count) {
+    if (MmioRead32 (GbeBar + R_GBE_MEM_CSR_MDIC) & B_GBE_MEM_CSR_MDIC_RB) {
+      return EFI_SUCCESS;
+    }
+    MicroSecondDelay (GBE_ACQUIRE_MDIO_DELAY);
+  }
+  DEBUG ((DEBUG_ERROR, "GbeMdiWaitReady Timeout reached. MDIO operation failed to complete in %d micro seconds\n", GBE_MAX_LOOP_TIME * GBE_ACQUIRE_MDIO_DELAY));
+  return EFI_TIMEOUT;
+}
+
+/**
+  Acquire MDIO software semaphore.
+
+  1. Ensure that MBARA offset F00h [5] = 1b
+  2. Poll MBARA offset F00h [5] up to 200ms
+
+  @param [in] GbeBar   GbE MMIO space
+
+  @retval EFI_SUCCESS
+  @retval EFI_TIMEOUT
+**/
+EFI_STATUS
+GbeMdiAcquireMdio (
+  IN      UINT32  GbeBar
+  )
+{
+  UINT32  ExtCnfCtrl;
+  UINT32  Count;
+
+  MmioOr32 (GbeBar + R_GBE_MEM_CSR_EXTCNF_CTRL, B_GBE_MEM_CSR_EXTCNF_CTRL_SWFLAG);
+  for (Count = 0; Count < GBE_MAX_LOOP_TIME; ++Count) {
+    ExtCnfCtrl = MmioRead32 (GbeBar + R_GBE_MEM_CSR_EXTCNF_CTRL);
+    if (ExtCnfCtrl & B_GBE_MEM_CSR_EXTCNF_CTRL_SWFLAG) {
+      return EFI_SUCCESS;
+    }
+    MicroSecondDelay (GBE_ACQUIRE_MDIO_DELAY);
+  }
+  DEBUG ((DEBUG_ERROR, "GbeMdiAcquireMdio Timeout. Unable to acquire MDIO Semaphore in %d micro seconds\n", GBE_MAX_LOOP_TIME * GBE_ACQUIRE_MDIO_DELAY));
+  return EFI_TIMEOUT;
+}
+
+/**
+  Release MDIO software semaphore by clearing MBARA offset F00h [5]
+
+  @param [in]  GbeBar   GbE MMIO space
+**/
+VOID
+GbeMdiReleaseMdio (
+  IN      UINT32  GbeBar
+  )
+{
+  ASSERT (MmioRead32 (GbeBar + R_GBE_MEM_CSR_EXTCNF_CTRL) & B_GBE_MEM_CSR_EXTCNF_CTRL_SWFLAG);
+  MmioAnd32 (GbeBar + R_GBE_MEM_CSR_EXTCNF_CTRL, (UINT32) ~B_GBE_MEM_CSR_EXTCNF_CTRL_SWFLAG);
+  ASSERT ((MmioRead32 (GbeBar + R_GBE_MEM_CSR_EXTCNF_CTRL) & B_GBE_MEM_CSR_EXTCNF_CTRL_SWFLAG) == 0);
+}
+
+/**
+  Sets page on MDI
+  Page setting is attempted twice.
+  If first attempt failes MAC and the Phy are force to be on SMBus.
+
+  Waits 4 mSec after page setting
+
+  @param [in]  GbeBar  GbE MMIO space
+  @param [in]  Data    Value to write in lower 16bits.
+
+  @retval EFI_SUCCESS       Page setting was successfull
+  @retval EFI_DEVICE_ERROR  Returned if both attermps of setting page failed
+**/
+EFI_STATUS
+GbeMdiSetPage (
+  IN      UINT32  GbeBar,
+  IN      UINT32  Page
+  )
+{
+  EFI_STATUS  Status;
+
+  MmioWrite32 (GbeBar + R_GBE_MEM_CSR_MDIC, (~B_PHY_MDI_READY) & (B_PHY_MDI_WRITE | B_PHY_MDI_PHY_ADDRESS_01 | R_PHY_MDI_PHY_REG_SET_PAGE | ((Page * 32) & 0xFFFF)));
+
+  Status = GbeMdiWaitReady (GbeBar);
+
+  if (Status == EFI_TIMEOUT) {
+    DEBUG ((DEBUG_INFO, "GbeMdiSetPage Timeout reached. Forcing the interface between the MAC and the Phy to be on SMBus\n"));
+    GbeMdiForceMacToSmb (GbeBar);
+    //
+    // Retry page setting
+    //
+    MmioWrite32 (GbeBar + R_GBE_MEM_CSR_MDIC, (~B_PHY_MDI_READY) & (B_PHY_MDI_WRITE | B_PHY_MDI_PHY_ADDRESS_01 | R_PHY_MDI_PHY_REG_SET_PAGE | ((Page * 32) & 0xFFFF)));
+    Status = GbeMdiWaitReady (GbeBar);
+    if (Status == EFI_TIMEOUT) {
+      DEBUG ((DEBUG_ERROR, "GbeMdiSetPage retry page setting failed!\n"));
+      return EFI_DEVICE_ERROR;
+    }
+  }
+
+  //
+  // Delay required for page to set properly
+  //
+  MicroSecondDelay (GBE_MDI_SET_PAGE_DELAY);
+
+  return Status;
+}
+
+/**
+  Sets Register in current page.
+
+  @param [in]  GbeBar      GbE MMIO space
+  @param [in]  register    Register number valid only in lower 16 Bits
+
+  @return EFI_STATUS
+**/
+EFI_STATUS
+GbeMdiSetRegister (
+  IN      UINT32  GbeBar,
+  IN      UINT32  Register
+  )
+{
+  MmioWrite32 (GbeBar + R_GBE_MEM_CSR_MDIC, (~B_PHY_MDI_READY) & (B_PHY_MDI_WRITE | B_PHY_MDI_PHY_ADDRESS_01 | R_PHY_MDI_PHY_REG_SET_ADDRESS | (Register & 0xFFFF)));
+  return GbeMdiWaitReady (GbeBar);
+}
+
+/**
+  Perform MDI write.
+
+  @param [in]  GbeBar       GbE MMIO space
+  @param [in]  PhyAddress   Phy Address General - 02 or Specific - 01
+  @param [in]  PhyRegister  Phy Register
+  @param [in]  WriteData    Value to write in lower 16bits.
+
+  @retval EFI_SUCCESS            Based on response from GbeMdiWaitReady
+  @retval EFI_TIMEOUT            Based on response from GbeMdiWaitReady
+  @retval EFI_INVALID_PARAMETER  If Phy Address or Register validaton failed
+**/
+EFI_STATUS
+GbeMdiWrite (
+  IN      UINT32  GbeBar,
+  IN      UINT32  PhyAddress,
+  IN      UINT32  PhyRegister,
+  IN      UINT32  WriteData
+  )
+{
+  if(!IsPhyAddressRegisterValid (PhyAddress, PhyRegister)) {
+    DEBUG ((DEBUG_ERROR, "GbeMdiWrite PhyAddressRegister validaton failed!\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  MmioWrite32 (GbeBar + R_GBE_MEM_CSR_MDIC, (~B_PHY_MDI_READY) & (B_PHY_MDI_WRITE | PhyAddress | PhyRegister | (WriteData & 0xFFFF)));
+  return GbeMdiWaitReady (GbeBar);
+}
+
+/**
+  Perform MDI read.
+
+  @param [in]  GbeBar       GbE MMIO space
+  @param [in]  PhyAddress   Phy Address General - 02 or Specific - 01
+  @param [in]  PhyRegister  Phy Register
+  @param [out] ReadData     Return Value
+
+  @retval EFI_SUCCESS            Based on response from GbeMdiWaitReady
+  @retval EFI_TIMEOUT            Based on response from GbeMdiWaitReady
+  @retval EFI_INVALID_PARAMETER  If Phy Address or Register validaton failed
+**/
+EFI_STATUS
+GbeMdiRead (
+  IN      UINT32  GbeBar,
+  IN      UINT32  PhyAddress,
+  IN      UINT32  PhyRegister,
+  OUT     UINT16  *ReadData
+  )
+{
+  EFI_STATUS    Status;
+
+  if(!IsPhyAddressRegisterValid (PhyAddress, PhyRegister)) {
+    DEBUG ((DEBUG_ERROR, "GbeMdiRead PhyAddressRegister validaton failed!\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  MmioWrite32 (GbeBar + R_GBE_MEM_CSR_MDIC, (~B_PHY_MDI_READY) & (B_PHY_MDI_READ | PhyAddress | PhyRegister));
+  Status = GbeMdiWaitReady (GbeBar);
+  if (EFI_SUCCESS == Status) {
+    *ReadData = (UINT16) MmioRead32 (GbeBar + R_GBE_MEM_CSR_MDIC);
+  }
+  return Status;
+}
+
+/**
+  Gets Phy Revision and Model Number
+  from PHY IDENTIFIER register 2 (offset 3)
+
+  @param [in]  GbeBar           GbE MMIO space
+  @param [out] LanPhyRevision   Return Value
+
+  @return EFI_STATUS
+  @return EFI_INVALID_PARAMETER When GbeBar is incorrect
+                                When Phy register or address is out of bounds
+**/
+EFI_STATUS
+GbeMdiGetLanPhyRevision (
+  IN      UINT32  GbeBar,
+  OUT     UINT16  *LanPhyRevision
+  )
+{
+  EFI_STATUS    Status;
+  UINT8         LpcdLoop;
+  UINT8         Delay;
+
+  if (!((GbeBar & 0xFFFFF000) > 0)) {
+    DEBUG ((DEBUG_ERROR, "GbeMdiGetLanPhyRevision GbeBar validation failed! Bar: 0x%08X \n", GbeBar));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = GbeMdiAcquireMdio (GbeBar);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "GbeMdiGetLanPhyRevision failed to aquire MDIO semaphore. Status: %r\n", Status));
+    return Status;
+  }
+
+  Status = GbeMdiSetPage (GbeBar, PHY_MDI_PAGE_769_PORT_CONTROL_REGISTERS);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "GbeMdiGetLanPhyRevision failed to Set Page 769. Status: %r\n", Status));
+    GbeMdiReleaseMdio (GbeBar);
+    return Status;
+  }
+
+  //
+  //  Set register to: Custom Mode Control
+  //   Reduced MDIO frequency access (slow mdio)
+  //   BIT 10 set to 1
+  //
+  Status = GbeMdiWrite (GbeBar, B_PHY_MDI_PHY_ADDRESS_01, MDI_REG_SHIFT (R_PHY_MDI_PAGE_769_REGISETER_16_CMC), BIT13 | B_PHY_MDI_PAGE_769_REGISETER_16_CMC_MDIO_FREQ_ACCESS | BIT8 | BIT7);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "GbeMdiGetLanPhyRevision failed to enable slow MDIO mode. Status: %r\n", Status));
+    GbeMdiReleaseMdio (GbeBar);
+    return Status;
+  }
+
+  //
+  // Read register PHY Version from PHY IDENTIFIER 2 (offset 0x3)
+  //  Bits [9:4]   - Device Model Number
+  //  Bits [3:0]   - Device Revision Number
+  //
+  Status = GbeMdiRead (GbeBar, B_PHY_MDI_PHY_ADDRESS_02, R_PHY_MDI_GENEREAL_REGISTER_03_PHY_IDENTIFIER_2, LanPhyRevision);
+
+  //
+  // Failed to obtain PHY REV
+  //
+  if (*LanPhyRevision == 0x0) {
+    if ((MmioRead32 (GbeBar + R_GBE_MEM_CSR_CTRL) & (B_GBE_MEM_CSR_CTRL_LANPHYPC_OVERRIDE | B_GBE_MEM_CSR_CTRL_LANPHYPC_VAL))) {
+      DEBUG ((DEBUG_ERROR, "GbeMdiGetLanPhyRevision failed to read Phy Revision. Other component tried to initialize GbE and failed.\n"));
+      Status = EFI_DEVICE_ERROR;
+      goto phy_exit;
+    }
+    DEBUG ((DEBUG_INFO, "GbeMdiGetLanPhyRevision failed to read Revision. Overriding LANPHYPC\n", Status));
+    //
+    // Taking over LANPHYPC
+    // 1. SW signal override - 1st cycle.
+    // 2. Turn LCD on - 2nd cycle.
+    //
+    MmioOr32 (GbeBar + R_GBE_MEM_CSR_CTRL, B_GBE_MEM_CSR_CTRL_LANPHYPC_OVERRIDE);
+    MmioOr32 (GbeBar + R_GBE_MEM_CSR_CTRL, B_GBE_MEM_CSR_CTRL_LANPHYPC_VAL);
+
+    //
+    // Poll on LPCD for 100mSec
+    //
+    LpcdLoop = 101;
+    while (LpcdLoop > 0) {
+      if (MmioRead32 (GbeBar + R_GBE_MEM_CSR_CTRL_EXT) & B_GBE_MEM_CSR_CTRL_EXT_LPCD) {
+        break;
+      } else {
+        LpcdLoop--;
+        MicroSecondDelay (1000);
+      }
+    }
+
+    if (LpcdLoop > 0) {
+      Delay = 100;
+      Status = GbeMdiRead (GbeBar, B_PHY_MDI_PHY_ADDRESS_02, R_PHY_MDI_GENEREAL_REGISTER_03_PHY_IDENTIFIER_2, LanPhyRevision);
+      while (*LanPhyRevision == 0 && Delay > 0) {
+        Status = GbeMdiRead (GbeBar, B_PHY_MDI_PHY_ADDRESS_02, R_PHY_MDI_GENEREAL_REGISTER_03_PHY_IDENTIFIER_2, LanPhyRevision);
+        if (EFI_ERROR(Status)) {
+          break;
+        }
+        MicroSecondDelay (1000);
+        Delay --;
+      }
+    }
+    //
+    // Restore LANPHYPC
+    // 1. Turn LCD off - 1st cycle.
+    // 2. Remove SW signal override - 2nd cycle.
+    //
+    MmioAnd32 (GbeBar + R_GBE_MEM_CSR_CTRL, (UINT32) ~B_GBE_MEM_CSR_CTRL_LANPHYPC_VAL);
+    MmioAnd32 (GbeBar + R_GBE_MEM_CSR_CTRL, (UINT32) ~B_GBE_MEM_CSR_CTRL_LANPHYPC_OVERRIDE);
+  }
+
+phy_exit:
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "GbeMdiGetLanPhyRevision failed to read Revision and Model Number from PHY Identifier 2. Status: %r\n", Status));
+    GbeMdiReleaseMdio (GbeBar);
+    return Status;
+  }
+
+  //
+  //  Switch back to normal MDIO frequency access
+  //
+  Status = GbeMdiWrite (GbeBar, B_PHY_MDI_PHY_ADDRESS_01,  MDI_REG_SHIFT (R_PHY_MDI_PAGE_769_REGISETER_16_CMC), (~B_PHY_MDI_PAGE_769_REGISETER_16_CMC_MDIO_FREQ_ACCESS) & (BIT13 | BIT8 | BIT7));
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "GbeMdiGetLanPhyRevision failed to disable slow MDIO mode. Status: %r\n", Status));
+  }
+
+  GbeMdiReleaseMdio (GbeBar);
+
+  return Status;
+}
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/LibraryPrivate/PeiDxeSmmGbeMdiLib/PeiDxeSmmGbeMdiLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/LibraryPrivate/PeiDxeSmmGbeMdiLib/PeiDxeSmmGbeMdiLib.inf
new file mode 100644
index 0000000000..99a01177f6
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/LibraryPrivate/PeiDxeSmmGbeMdiLib/PeiDxeSmmGbeMdiLib.inf
@@ -0,0 +1,34 @@
+## @file
+# Gbe MDI Library.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmGbeMdiLib
+FILE_GUID = 0360E6F6-892A-4852-BF98-15C0D30D8A48
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = GbeMdiLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+TimerLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+GbeMdiLib.c
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 17/40] TigerlakeSiliconPkg/IpBlock: Add Gpio component
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (14 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 16/40] TigerlakeSiliconPkg/IpBlock: Add Gbe component Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 18/40] TigerlakeSiliconPkg/IpBlock: Add Graphics component Heng Luo
                   ` (22 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * IpBlock/Gpio/Include
  * IpBlock/Gpio/IncludePrivate
  * IpBlock/Gpio/Library
  * IpBlock/Gpio/LibraryPrivate

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Include/Library/GpioCheckConflictLib.h                                 |   43 ++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/DxeGpioPolicyLib.h                              |   55 +++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioHelpersLib.h                                |  105 +++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioNameBufferLib.h                             |   23 +++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioPrivateLib.h                                | 1197 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.c            |  140 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.inf          |   29 +++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.c    |   35 +++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf  |   26 ++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioInit.c                                    |  558 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioLib.c                                     | 2387 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioLibrary.h                                 |   82 ++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioNames.c                                   |   86 ++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioNativeLib.c                               |  193 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf                          |   49 ++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c         |  119 ++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf       |   26 ++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioNameBufferLib/DxeGpioNameBufferLib.inf           |   32 ++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioNameBufferLib/GpioNameBufferDxe.c                |   19 +++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioPolicyLib/DxeGpioPolicyLib.c                     |   87 ++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioPolicyLib/DxeGpioPolicyLib.inf                   |   31 ++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioNamesVer2.c                 |   88 +++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c                |  395 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLibVer2.c            |  131 ++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibVer2.inf |   46 +++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.c                   |  413 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.inf                 |   48 ++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioNameBufferLib/GpioNameBufferPei.c                |   67 +++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioNameBufferLib/PeiGpioNameBufferLib.inf           |   35 +++++++++++++
 29 files changed, 6545 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Include/Library/GpioCheckConflictLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Include/Library/GpioCheckConflictLib.h
new file mode 100644
index 0000000000..5e3dd90ae6
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Include/Library/GpioCheckConflictLib.h
@@ -0,0 +1,43 @@
+/** @file
+  Header file for checking Gpio PadMode conflict.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _GPIO_CHECK_CONFLICT_LIB_H_
+#define _GPIO_CHECK_CONFLICT_LIB_H_
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/GpioConfig.h>
+#include <Library/GpioLib.h>
+
+extern EFI_GUID gGpioCheckConflictHobGuid;
+
+typedef struct {
+  GPIO_PAD  GpioPad;
+  UINT32    GpioPadMode:5;
+  UINT32    Reserved:27;
+} GPIO_PAD_MODE_INFO;
+
+/**
+  Check Gpio PadMode conflict and report it.
+**/
+VOID
+GpioCheckConflict (
+  VOID
+  );
+
+/**
+  This library will create one Hob for each Gpio config table
+  without PadMode is GpioHardwareDefault
+
+  @param[in]  GpioDefinition    Point to Platform Gpio table
+  @param[in]  GpioTableCount    Number of Gpio table entries
+**/
+VOID
+CreateGpioCheckConflictHob (
+  IN GPIO_INIT_CONFIG          *GpioDefinition,
+  IN UINT32                    GpioTableCount
+  );
+
+#endif // _GPIO_CHECK_CONFLICT_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/DxeGpioPolicyLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/DxeGpioPolicyLib.h
new file mode 100644
index 0000000000..d86e6624b7
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/DxeGpioPolicyLib.h
@@ -0,0 +1,55 @@
+/** @file
+  DXE Gpio policy library.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _DXE_GPIO_POLICY_LIB_H_
+#define _DXE_GPIO_POLICY_LIB_H_
+
+#include <Protocol/PchPolicy.h>
+
+/**
+  Print GPIO_DXE_CONFIG and serial out.
+
+  @param[in] PchPolicy            Pointer to a PCH_POLICY_PROTOCOL
+**/
+VOID
+GpioDxePrintConfig (
+  IN PCH_POLICY_PROTOCOL    *PchPolicy
+  );
+
+/**
+  Load DXE Config block default for GPIO
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+GpioDxeLoadConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  );
+
+/**
+  Get Gpio config block table size.
+
+  @retval      Size of config block
+**/
+UINT16
+GpioDxeGetConfigBlockTotalSize (
+  VOID
+  );
+
+/**
+  Add Gpio ConfigBlock.
+
+  @param[in] ConfigBlockTableAddress    The pointer to config block table
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+GpioDxeAddConfigBlock (
+  IN VOID           *ConfigBlockTableAddress
+  );
+
+#endif // _DXE_GPIO_POLICY_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioHelpersLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioHelpersLib.h
new file mode 100644
index 0000000000..d2a8d24c8a
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioHelpersLib.h
@@ -0,0 +1,105 @@
+/** @file
+  Header file for GPIO Helpers Lib implementation.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _GPIO_HELPERS_LIB_H_
+#define _GPIO_HELPERS_LIB_H_
+
+#include <Library/GpioConfig.h>
+
+/**
+  This procedure stores GPIO pad unlock information
+
+  @param[in] GpioPad         GPIO pad
+  @param[in] GpioLockConfig  GPIO Lock Configuration
+
+  @retval Status
+**/
+EFI_STATUS
+GpioStoreUnlockData (
+  IN GPIO_PAD             GpioPad,
+  IN GPIO_LOCK_CONFIG     GpioLockConfig
+  );
+
+/**
+  This procedure stores GPIO group data about pads which PadConfig needs to be unlocked.
+
+  @param[in]  GroupIndex          GPIO group index
+  @param[in]  DwNum               DWORD index for a group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in]  PadsToLock          DWORD bitmask for pads which are going to be left unlocked
+                                  Bit position - PadNumber
+                                  Bit value - 0: Skip, 1: Leave unlocked
+
+  @retval Status
+**/
+EFI_STATUS
+GpioStoreGroupDwUnlockPadConfigData (
+  IN UINT32                       GroupIndex,
+  IN UINT32                       DwNum,
+  IN UINT32                       UnlockedPads
+  );
+
+/**
+  This procedure stores GPIO group data about pads which Output state needs to be unlocked.
+
+  @param[in]  GroupIndex          GPIO group index
+  @param[in]  DwNum               DWORD index for a group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in]  PadsToLock          DWORD bitmask for pads which are going to be left unlocked
+                                  Bit position - PadNumber
+                                  Bit value - 0: Skip, 1: Leave unlocked
+
+  @retval Status
+**/
+EFI_STATUS
+GpioStoreGroupDwUnlockOutputData (
+  IN UINT32                       GroupIndex,
+  IN UINT32                       DwNum,
+  IN UINT32                       UnlockedPads
+  );
+
+/**
+  This procedure will get GPIO group data with pads, which PadConfig is supposed to be left unlock
+
+  @param[in]  GroupIndex          GPIO group index
+  @param[in]  DwNum               DWORD index for a group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @retval     UnlockedPads        DWORD bitmask for pads which are going to be left unlocked
+                                  Bit position - PadNumber
+                                  Bit value - 0: to be locked, 1: Leave unlocked
+**/
+UINT32
+GpioGetGroupDwUnlockPadConfigMask (
+  IN UINT32                       GroupIndex,
+  IN UINT32                       DwNum
+  );
+
+/**
+  This procedure will get GPIO group data with pads, which Output is supposed to be left unlock
+
+  @param[in]  GroupIndex          GPIO group index
+  @param[in]  DwNum               DWORD index for a group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @retval     UnlockedPads        DWORD bitmask for pads which are going to be left unlocked
+                                  Bit position - PadNumber
+                                  Bit value - 0: to be locked, 1: Leave unlocked
+**/
+UINT32
+GpioGetGroupDwUnlockOutputMask (
+  IN UINT32                       GroupIndex,
+  IN UINT32                       DwNum
+  );
+
+/**
+  Returns Gpio Override Level1 Information
+
+  @retval  TRUE/FALSE GPIO Override Level 1 Enabled/Disabled
+**/
+BOOLEAN
+GpioOverrideLevel1Enabled (
+  VOID
+  );
+#endif // _GPIO_HELPERS_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioNameBufferLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioNameBufferLib.h
new file mode 100644
index 0000000000..c60709c637
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioNameBufferLib.h
@@ -0,0 +1,23 @@
+/** @file
+  Header file for GpioMemLib. This library provides GpioLib with static memory to hold GpioName.
+  Static memory is handled differently in PEI and DXE phase. For PEI pre mem we use private HOB to store
+  gpio name since .data section is read only. For PEI post mem and DXE simple static buffer is used.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _GPIO_NAME_BUFFER_LIB_H_
+#define _GPIO_NAME_BUFFER_LIB_H_
+
+#define GPIO_NAME_LENGTH_MAX  32
+
+/**
+  Returns pointer to the global buffer to be used by GpioNamesLib
+
+  @retval CHAR8*  Pointer to the buffer
+**/
+CHAR8*
+GpioGetStaticNameBuffer (
+  VOID
+  );
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioPrivateLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioPrivateLib.h
new file mode 100644
index 0000000000..be41f80c24
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioPrivateLib.h
@@ -0,0 +1,1197 @@
+/** @file
+  Header file for GpioPrivateLib.
+  All function in this library is available for PEI, DXE, and SMM,
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _GPIO_PRIVATE_LIB_H_
+#define _GPIO_PRIVATE_LIB_H_
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/GpioConfig.h>
+#include <Library/PchPcrLib.h>
+#include <TcssPeiConfig.h>
+
+/**
+  GPIO Standby State configuration
+  Standby State options for GPIO Pads
+**/
+typedef enum {
+  GpioIosStateDefault         = 0x0,
+  GpioIosStateLatchLastValue  = (0x0 << 1) | 0x01,  ///< Latch last value driven on TX, TX Enable and RX Enable
+  GpioIosStateTx0Rx0RxDis     = (0x1 << 1) | 0x01,  ///< TX: 0, RX: 0 (internally), RX disabled
+  GpioIosStateTx0Rx1RxDis     = (0x2 << 1) | 0x01,  ///< TX: 0, RX: 1 (internally), RX disabled
+  GpioIosStateTx1Rx0RxDis     = (0x3 << 1) | 0x01,  ///< TX: 1, RX: 0 (internally), RX disabled
+  GpioIosStateTx1Rx1RxDis     = (0x4 << 1) | 0x01,  ///< TX: 1, RX: 1 (internally), RX disabled
+  GpioIosStateTx0RxEn         = (0x5 << 1) | 0x01,  ///< TX: 0, RX enabled
+  GpioIosStateTx1RxEn         = (0x6 << 1) | 0x01,  ///< TX: 1, RX enabled
+  GpioIosStateHizRx0          = (0x7 << 1) | 0x01,  ///< Hi-Z, RX: 0 (internally)
+  GpioIosStateHizRx1          = (0x8 << 1) | 0x01,  ///< Hi-Z, RX: 1 (internally)
+  GpioIosStateTxDisRxEn       = (0x9 << 1) | 0x01,  ///< TX Disabled and RX Enabled (i.e. wake or interrupt)
+  GpioIosStateMasked          = (0xF << 1) | 0x01   ///< IO Standby signal is masked for this pad. In this mode, a pad operates as if IOStandby has not been asserted.
+} GPIO_IOSTANDBY_STATE;
+
+/**
+  GPIO Standby Term configuration
+  Standby Termination options for GPIO Pads
+**/
+typedef enum {
+  GpioIosTermDefault         = 0x00,
+  GpioIosTermSame            = (0x00 << 1) | 0x01, ///< Same as state specified in Term
+  GpioIosTermPuDisPdDis      = (0x01 << 1) | 0x01, ///< Disable Pullup and Pulldown
+  GpioIosTermPuDisPdEn       = (0x02 << 1) | 0x01, ///< Enable Pulldown
+  GpioIosTermPuEnPdDis       = (0x03 << 1) | 0x01  ///< Enable Pullup
+} GPIO_IOSTANDBY_TERM;
+
+//
+// Structure for native pin data
+//
+typedef struct {
+  GPIO_PAD              Pad;
+  GPIO_PAD_MODE         Mode;
+  GPIO_IOSTANDBY_STATE  IosState;
+  GPIO_IOSTANDBY_TERM   IosTerm;
+} GPIO_PAD_NATIVE_FUNCTION;
+
+//
+// Structure for Serial GPIO pin definition
+//
+typedef struct {
+  GPIO_PAD_NATIVE_FUNCTION  Sclock;
+  GPIO_PAD_NATIVE_FUNCTION  Sload;
+  GPIO_PAD_NATIVE_FUNCTION  Sdataout;
+} SGPIO_PINS;
+
+//
+// Structure for USB Virtual Wire OverCurrent Pad Mode group
+//
+typedef struct {
+  GPIO_PAD       OcRxPad;
+  GPIO_PAD       OcTxPad;
+} GPIO_VWOC_FUNCTION;
+
+//
+// Below defines are based on GPIO_CONFIG structure fields
+//
+#define B_GPIO_PAD_MODE_MASK                            0xF
+#define N_GPIO_PAD_MODE_BIT_POS                         0
+#define B_GPIO_HOSTSW_OWN_MASK                          0x3
+#define N_GPIO_HOSTSW_OWN_BIT_POS                       0
+#define B_GPIO_DIRECTION_MASK                           0x1F
+#define B_GPIO_DIRECTION_DIR_MASK                       0x7
+#define N_GPIO_DIRECTION_DIR_BIT_POS                    0
+#define B_GPIO_DIRECTION_INV_MASK                       0x18
+#define N_GPIO_DIRECTION_INV_BIT_POS                    3
+#define B_GPIO_OUTPUT_MASK                              0x3
+#define N_GPIO_OUTPUT_BIT_POS                           0
+#define N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS            0
+#define N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS              5
+#define B_GPIO_RESET_CONFIG_RESET_MASK                  0x3F
+#define N_GPIO_RESET_CONFIG_OLD_RESET_TYPE              BIT1
+#define B_GPIO_RESET_CONFIG_OLD_RESET_MASK              0xF
+#define N_GPIO_RESET_CONFIG_RESET_BIT_POS               0
+#define B_GPIO_RESET_CONFIG_GPD_RESET_MASK              (BIT5 | BIT4)
+#define B_GPIO_RESET_CONFIG_GPP_RESET_MASK              (BIT3 | BIT2)
+#define N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS    0
+#define N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS               0
+#define B_GPIO_GPIO_IOSTANDBY_STATE_MASK                ((0xF << 1) | 0x01)
+#define B_GPIO_GPIO_IOSTANDBY_STATE_POS                 0
+#define B_GPIO_GPIO_IOSTANDBY_TERM_MASK                 ((0x2 << 1) | 0x01)
+#define B_GPIO_GPIO_IOSTANDBY_TERM_POS                  0
+
+//
+// Structure for storing information about registers offset, community,
+// maximal pad number for available groups
+//
+typedef struct {
+  PCH_SBI_PID  Community;
+  UINT16       PadOwnOffset;
+  UINT16       HostOwnOffset;
+  UINT16       GpiIsOffset;
+  UINT16       GpiIeOffset;
+  UINT16       GpiGpeStsOffset;
+  UINT16       GpiGpeEnOffset;
+  UINT16       SmiStsOffset;
+  UINT16       SmiEnOffset;
+  UINT16       NmiStsOffset;
+  UINT16       NmiEnOffset;
+  UINT16       PadCfgLockOffset;
+  UINT16       PadCfgLockTxOffset;
+  UINT16       PadCfgOffset;
+  UINT16       PadPerGroup;
+} GPIO_GROUP_INFO;
+
+//
+// If in GPIO_GROUP_INFO structure certain register doesn't exist
+// it will have value equal to NO_REGISTER_FOR_PROPERTY
+//
+#define NO_REGISTER_FOR_PROPERTY 0xFFFF
+
+#define GPIO_PAD_DEF(Group,Pad)                (UINT32)(((Group) << 16) + (Pad))
+#define GPIO_GROUP_DEF(GroupIndex,ChipsetId)   ((GroupIndex) | ((ChipsetId) << 8))
+#define GPIO_GET_GROUP_INDEX(Group)            ((Group) & 0x1F)
+#define GPIO_GET_GROUP_FROM_PAD(GpioPad)       (((GpioPad) & 0x0F1F0000) >> 16)
+#define GPIO_GET_GROUP_INDEX_FROM_PAD(GpioPad) GPIO_GET_GROUP_INDEX (GPIO_GET_GROUP_FROM_PAD(GpioPad))
+#define GPIO_GET_PAD_NUMBER(GpioPad)           ((GpioPad) & 0x1FF)
+#define GPIO_GET_CHIPSET_ID(GpioPad)           (((GpioPad) >> 24) & 0xF)
+
+#define GPIO_GET_PAD_POSITION(PadNumber)       ((PadNumber) % 32)
+#define GPIO_GET_DW_NUM(PadNumber)             ((PadNumber) / 32u)
+
+/**
+  This procedure will retrieve address and length of GPIO info table
+
+  @param[out]  GpioGroupInfoTableLength   Length of GPIO group table
+
+  @retval Pointer to GPIO group table
+**/
+CONST GPIO_GROUP_INFO*
+GpioGetGroupInfoTable (
+  OUT UINT32              *GpioGroupInfoTableLength
+  );
+
+typedef struct {
+  CONST CHAR8*    GpioGroupPrefix;
+  CONST GPIO_PAD  FirstUniqueGpio;
+  CONST CHAR8**   GroupUniqueNames;
+  CONST UINT32    UniqueNamesTableSize;
+} GPIO_GROUP_NAME_INFO;
+
+//
+// Helper macros for initializing GPIO_GROUP_NAME_INFO structures
+//
+#define GPIO_GROUP_NAME(GroupName,FirstUniqueGpio,GroupUniqueNamesTable) \
+  {GroupName, FirstUniqueGpio, GroupUniqueNamesTable, ARRAY_SIZE (GroupUniqueNamesTable)}
+
+#define GPIO_GROUP_NAME_BASIC(GroupName) \
+  {GroupName, 0, NULL, 0}
+
+/**
+  Returns GPIO_GROUP_NAME_INFO corresponding to the give GpioPad
+
+  @param[in]  GroupIndex  Group index
+
+  @retval  GPIO_GROUP_NAME_INFO*  Pointer to the GPIO_GROUP_NAME_INFO
+  @retval  NULL                   If no group descriptor was found
+**/
+CONST
+GPIO_GROUP_NAME_INFO*
+GpioGetGroupNameInfo (
+  IN UINT32  GroupIndex
+  );
+
+/**
+  Get GPIO Chipset ID specific to PCH generation and series
+**/
+UINT32
+GpioGetThisChipsetId (
+  VOID
+  );
+
+/**
+  This procedure is used to check if GpioPad is valid for certain chipset
+
+  @param[in]  GpioPad             GPIO pad
+
+  @retval TRUE                    This pin is valid on this chipset
+          FALSE                   Incorrect pin
+**/
+BOOLEAN
+GpioIsCorrectPadForThisChipset (
+  IN  GPIO_PAD        GpioPad
+  );
+
+/**
+  Generates GPIO name from GpioPad
+  This function returns pointer to the static buffer.
+
+  @param[in] GpioPad  GpioPad
+
+  @retval CHAR8*  Pointer to the GPIO name
+**/
+CHAR8*
+GpioName (
+  IN GPIO_PAD  GpioPad
+  );
+
+/**
+  Generates GPIO name from GpioNativePad
+  This function returns pointer to the static buffer.
+
+  @param[in] GpioNativePad  GpioNativePad
+
+  @retval CHAR8*  Pointer to the GPIO name
+**/
+CHAR8*
+GpioPinMuxName (
+  IN GPIO_NATIVE_PAD  GpioNativePad
+  );
+
+/**
+  Generates GPIO Pad Termination string
+  This function returns pointer to the static buffer.
+
+  @param[in] GpioPadTermination  GPIO Pad Termination
+
+  @retval CHAR8*  Painter to the pad termianation string
+**/
+CHAR8*
+GpioGetPadTerminationString (
+  IN GPIO_ELECTRICAL_CONFIG PadTermination
+  );
+
+/**
+  This procedure will get value of selected gpio register
+
+  @param[in]  Group               GPIO group number
+  @param[in]  Offset              GPIO register offset
+  @param[out] RegVal              Value of gpio register
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioGetReg (
+  IN  GPIO_GROUP              Group,
+  IN  UINT32                  Offset,
+  OUT UINT32                  *RegVal
+  );
+
+/**
+  This procedure will set value of selected gpio register
+
+  @param[in] Group               GPIO group number
+  @param[in] Offset              GPIO register offset
+  @param[in] RegVal              Value of gpio register
+
+  @retval EFI_SUCCESS            The function completed successfully
+  @retval EFI_INVALID_PARAMETER  Invalid group or pad number
+**/
+EFI_STATUS
+GpioSetReg (
+  IN GPIO_GROUP              Group,
+  IN UINT32                  Offset,
+  IN UINT32                  RegVal
+  );
+
+/**
+  This procedure is used by PchSmiDispatcher and will return information
+  needed to register GPI SMI.
+
+  @param[in]  Index                   GPI SMI number
+  @param[out] GpioPin                 GPIO pin
+  @param[out] GpiSmiBitOffset         GPI SMI bit position within GpiSmi Registers
+  @param[out] GpiHostSwOwnRegAddress  Address of HOSTSW_OWN register
+  @param[out] GpiSmiStsRegAddress     Address of GPI SMI status register
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioGetPadAndSmiRegs (
+  IN UINT32            Index,
+  OUT GPIO_PAD         *GpioPin,
+  OUT UINT8            *GpiSmiBitOffset,
+  OUT UINT32           *GpiHostSwOwnRegAddress,
+  OUT UINT32           *GpiSmiStsRegAddress
+  );
+
+/**
+  This procedure will set GPIO Driver IRQ number
+
+  @param[in]  Irq                 Irq number
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid IRQ number
+**/
+EFI_STATUS
+GpioSetIrq (
+  IN  UINT8          Irq
+  );
+
+/**
+  This function provides GPIO Community PortIDs
+
+  @param[out] NativePinsTable                Table with GPIO COMMx SBI PortIDs
+
+  @retval      Number of communities
+**/
+UINT32
+GpioGetComSbiPortIds (
+  OUT PCH_SBI_PID    **GpioComSbiIds
+  );
+
+/**
+  This function provides list of GPIO for which IO Standby State configuration
+  has to be set as 'Masked'
+
+  @param[out] GpioPadsList                Table with pads
+
+  @retval      Number of pads
+**/
+UINT32
+GpioGetIoStandbyStateConfigurationPadsList (
+  OUT GPIO_PAD_NATIVE_FUNCTION    **GpioPadsList
+  );
+
+
+/**
+  This procedure will perform special handling of GPP_A_12.
+
+  @param[in]  None
+
+  @retval None
+**/
+VOID
+GpioA12SpecialHandling (
+  VOID
+  );
+
+//
+// Structure which stores information needed to map GPIO Group
+// to 1-Tier GPE. Configuration is needed both in PMC and GPIO IP.
+// Because GPE_DWx can handle only 32 pins only single double word can
+// be mapped at a time. Each DW for a group has different configuration in PMC and GPIO
+//
+typedef struct {
+  GPIO_GROUP  Group;
+  UINT8       GroupDw;
+  UINT8       PmcGpeDwxVal;
+} GPIO_GROUP_TO_GPE_MAPPING;
+
+/**
+  Get information for GPIO Group required to program GPIO and PMC for desired 1-Tier GPE mapping
+
+  @param[out] GpioGroupToGpeMapping        Table with GPIO Group to GPE mapping
+  @param[out] GpioGroupToGpeMappingLength  GPIO Group to GPE mapping table length
+**/
+VOID
+GpioGetGroupToGpeMapping (
+  OUT GPIO_GROUP_TO_GPE_MAPPING  **GpioGroupToGpeMapping,
+  OUT UINT32                     *GpioGroupToGpeMappingLength
+  );
+
+/**
+  This procedure will return Port ID of GPIO Community from GpioPad
+
+  @param[in] GpioPad            GpioPad
+
+  @retval GpioCommunityPortId   Port ID of GPIO Community
+**/
+UINT8
+GpioGetGpioCommunityPortIdFromGpioPad (
+  IN GPIO_PAD        GpioPad
+  );
+
+/**
+  This procedure will return PadCfg address from GpioPad
+
+  @param[in] GpioPad            GpioPad
+
+  @retval GpioPadCfgAddress     PadCfg Address of GpioPad
+**/
+UINT32
+GpioGetGpioPadCfgAddressFromGpioPad (
+  IN GPIO_PAD        GpioPad
+  );
+
+/**
+  This procedure is used to unlock all GPIO pads.
+  This function can only be called when platform is still in HOSTIA_BOOT_SAI.
+**/
+VOID
+GpioUnlockAllPads (
+  VOID
+  );
+
+/**
+  This procedure will check if GpioPad is owned by host.
+
+  @param[in] GpioPad       GPIO pad
+
+  @retval TRUE             GPIO pad is owned by host
+  @retval FALSE            GPIO pad is not owned by host and should not be used with GPIO lib API
+**/
+BOOLEAN
+GpioIsPadHostOwned (
+  IN GPIO_PAD             GpioPad
+  );
+
+
+/**
+  This procedure will check if GpioPad argument is valid.
+  Function will check below conditions:
+   - GpioPad represents a pad for current PCH
+   - GpioPad belongs to valid GpioGroup
+   - GPIO PadNumber is not greater than number of pads for this group
+
+  @param[in] GpioPad       GPIO pad
+
+  @retval TRUE             GPIO pad is valid and can be used with GPIO lib API
+  @retval FALSE            GPIO pad is invalid and cannot be used with GPIO lib API
+**/
+BOOLEAN
+GpioIsPadValid (
+  IN GPIO_PAD             GpioPad
+  );
+
+/**
+  This procedure will read GPIO Pad Configuration register
+
+  @param[in] GpioPad          GPIO pad
+  @param[in] DwReg            Choose PADCFG register: 0:DW0, 1:DW1
+
+  @retval PadCfgRegValue      PADCFG_DWx value
+**/
+UINT32
+GpioReadPadCfgReg (
+  IN GPIO_PAD             GpioPad,
+  IN UINT8                DwReg
+  );
+
+/**
+  This procedure will write or read GPIO Pad Configuration register
+
+  @param[in] GpioPad              GPIO pad
+  @param[in] DwReg                Choose PADCFG register: 0:DW0, 1:DW1
+  @param[in] PadCfgAndMask        Mask to be AND'ed with PADCFG reg value
+  @param[in] PadCfgOrMask         Mask to be OR'ed with PADCFG reg value
+
+  @retval none
+**/
+VOID
+GpioWritePadCfgReg (
+  IN GPIO_PAD             GpioPad,
+  IN UINT8                DwReg,
+  IN UINT32               PadCfgAndMask,
+  IN UINT32               PadCfgOrMask
+  );
+
+/**
+  This procedure will Enable USB Virtual Wire Overcurrent pin
+
+  @param[in] GpioPad             GPIO Pad
+
+  @retval EFI_SUCCESS
+**/
+EFI_STATUS
+GpioSetVwOverCurrentPin (
+  IN GPIO_VWOC_FUNCTION GpioPad
+  );
+
+/**
+  This procedure will set Native Function IOSF-SB Virtual Wire Message Generation bit
+  in DW0 of requested GPIO Pad
+
+  @param[in] GPIO_PAD   GpioPad
+**/
+VOID
+GpioSetNafVweBit (
+  IN CONST GPIO_PAD PadCfg
+  );
+
+/**
+  This procedure will set GPIO mode
+
+  @param[in] GpioPad             GPIO pad
+  @param[in] PadModeValue        GPIO pad mode value
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioSetPadMode (
+  IN GPIO_PAD                GpioPad,
+  IN GPIO_PAD_MODE           PadModeValue
+  );
+
+/**
+  This procedure will set GPIO pad to native mode.
+  To be used if no other settings are to be configured when enabling native mode.
+
+  @param[in]  GpioNativePad       GPIO Pad with native mode information
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioSetNativePad (
+  IN GPIO_NATIVE_PAD  GpioNativePad
+  );
+
+/**
+  This procedure will set GPIO pad to native function based on provided native function
+  and platform muxing selection (if needed).
+
+  @param[in]  PadFunction         PadMode for a specific native signal. Please refer to GpioNativePads.h
+  @param[in]  PinMux              GPIO Native pin mux platform config.
+                                  This argument is optional and needs to be
+                                  provided only if feature can be enabled
+                                  on multiple pads
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioSetNativePadByFunction (
+  IN UINT32  PadFunction,
+  IN UINT32  PinMux
+  );
+
+/**
+  This procedure will get GPIO mode
+
+  @param[in]  GpioPad             GPIO pad
+  @param[out] PadModeValue        GPIO pad mode value
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioGetPadMode (
+  IN  GPIO_PAD                 GpioPad,
+  OUT GPIO_PAD_MODE            *PadModeValue
+  );
+
+/**
+  This procedure will check if group is within DeepSleepWell.
+
+  @param[in]  Group               GPIO Group
+
+  @retval GroupWell               TRUE:  This is DSW Group
+                                  FALSE: This is not DSW Group
+**/
+BOOLEAN
+GpioIsDswGroup (
+  IN  GPIO_GROUP         Group
+  );
+
+/**
+  The function performs GPIO Power Management programming.
+**/
+VOID
+GpioConfigurePm (
+  VOID
+  );
+
+/**
+  This function performs initial IO Standby State related configurations
+**/
+VOID
+GpioConfigureIoStandbyState (
+  VOID
+  );
+
+/**
+  This function enables SCS SD Card controller card detect pin
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableScsSdCardDetect (
+  VOID
+  );
+
+/**
+  This function sets HDA SSP interface pins into native mode
+
+  @param[in]  SspInterfaceNumber   SSPx interface number
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableHdaSsp (
+  IN  UINT32            SspInterfaceNumber
+  );
+
+/**
+  This function sets HDA SSP Master Clock into native mode
+
+  @param[in]  MclkIndex       MCLK index
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableHdaSspMasterClock (
+  IN UINT32  MclkIndex
+  );
+
+/**
+  This function sets HDA SoundWire interface pins into native mode
+
+  @param[in]  SndwInterfaceNumber   SNDWx interface number
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableHdaSndw (
+  IN  UINT32            SndwInterfaceNumber
+  );
+
+/**
+  This function provides SPI IO pin for Touch Host Controller
+
+  @param[in]  SpiIndex                  SPI1 or SPI2 - 0 or 1
+  @param[in]  IoIndex                   IoIndex Valid from 0 (SPI_IO_0) to 3 (SPI_IO_3)
+
+  @retval     NativePin                 Native Pin Configuration, 0 if SpiIndex or IoIndex is invalid
+**/
+GPIO_PAD_NATIVE_FUNCTION
+GpioGetThcSpiIo (
+  IN  UINT32                      SpiIndex,
+  IN  UINT32                      IoIndex
+  );
+
+/**
+  This function provides SPI ChipSelect pin for Touch Host Controller
+
+  @param[in]  SpiIndex                  SPI1 or SPI2 - 0 or 1
+
+  @retval     NativePin                 Native Pin Configuration, 0 if SpiIndex is invalid
+**/
+GPIO_PAD_NATIVE_FUNCTION
+GpioGetThcSpiCs (
+  IN  UINT32                      SpiIndex
+  );
+
+/**
+  This function provides SPI Clock pin for Touch Host Controller
+
+  @param[in]  SpiIndex                  SPI1 or SPI2 - 0 or 1
+
+  @retval     NativePin                 Native Pin Configuration, 0 if SpiIndex is invalid
+**/
+GPIO_PAD_NATIVE_FUNCTION
+GpioGetThcSpiClk (
+  IN  UINT32                      SpiIndex
+  );
+
+/**
+  This function provides SPI Reset pin for Touch Host Controller
+
+  @param[in]  SpiIndex                  SPI1 or SPI2 - 0 or 1
+
+  @retval     NativePin                 Native Pin Configuration, 0 if SpiIndex is invalid
+**/
+GPIO_PAD_NATIVE_FUNCTION
+GpioGetThcSpiReset (
+  IN  UINT32                      SpiIndex
+  );
+
+/**
+  This function sets SMBUS controller pins into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSmbus (
+  VOID
+  );
+
+/**
+  This function sets SMBUS ALERT pins into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSmbusAlert (
+  VOID
+  );
+
+/**
+  This function provides Serial GPIO pins
+
+  @param[in]  SataCtrlIndex       SATA controller index
+  @param[out] SgpioPins           SATA Serial GPIO pins
+**/
+VOID
+GpioGetSataSgpioPins (
+  IN  UINT32        SataCtrlIndex,
+  OUT SGPIO_PINS    *SgpioPins
+  );
+
+/**
+  This function sets Serial GPIO pins into native mode
+
+  @param[in]  SataCtrlIndex       SATA controller index
+  @param[in]  SataPort            SATA port number
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSataSgpio (
+  IN  UINT32  SataCtrlIndex
+  );
+
+/**
+  This function enables USB OverCurrent pins by setting
+  USB2 OCB pins into native mode
+
+  @param[in]  OcPinNumber            USB OC pin number
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableUsbOverCurrent (
+  IN  UINTN   OcPinNumber
+  );
+
+/**
+  This function enables USB Virtual Wire OverCurrent pins by OcPinNumber.
+
+  @param[in]  OcPinNumber            USB OC pin number
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableUsbVwOverCurrent (
+  IN  UINTN   OcPinNumber
+  );
+
+/**
+  This function sets SATA DevSlp pins into native mode
+
+  @param[in]  SataCtrlIndex       SATA controller index
+  @param[in]  SataPort            SATA port number
+  @param[in]  ResetType           GPIO reset type (see GPIO_RESET_CONFIG in GpioConfig.h)
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSataDevSlpPin (
+  IN  UINT32  SataCtrlIndex,
+  IN  UINTN   SataPort,
+  IN  UINT32  ResetType
+  );
+
+/**
+  This function checks if SataDevSlp pin is in native mode
+
+  @param[in]  SataCtrlIndex       SATA controller index
+  @param[in]  SataPort            SATA port
+  @param[out] DevSlpPad           DevSlpPad
+                                  This is an optional parameter and may be NULL.
+
+  @retval TRUE                    DevSlp is in native mode
+          FALSE                   DevSlp is not in native mode
+**/
+BOOLEAN
+GpioIsSataDevSlpPinEnabled (
+  IN  UINT32          SataCtrlIndex,
+  IN  UINTN           SataPort,
+  OUT GPIO_PAD        *DevSlpPad  OPTIONAL
+  );
+
+/**
+  This function sets SATAGPx pin into native mode
+
+  @param[in]  SataCtrlIndex       SATA controller index
+  @param[in]  SataPort            SATA port number
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableSataGpPin (
+  IN  UINT32  SataCtrlIndex,
+  IN  UINTN   SataPort
+  );
+
+/**
+  This function provides SATA GP pin data
+
+  @param[in]  SataCtrlIndex       SATA controller index
+  @param[in]  SataPort            SATA port number
+  @param[out] NativePin           SATA GP pin
+**/
+VOID
+GpioGetSataGpPin (
+  IN  UINT32                    SataCtrlIndex,
+  IN  UINTN                     SataPort,
+  OUT GPIO_PAD_NATIVE_FUNCTION  *NativePin
+  );
+
+/**
+  This function sets SATA LED pin into native mode. SATA LED indicates
+  SATA controller activity
+
+  @param[in]  SataCtrlIndex       SATA controller index
+  @retval     Status
+**/
+EFI_STATUS
+GpioEnableSataLed (
+  IN  UINT32                    SataCtrlIndex
+  );
+
+/**
+  Returns pad for given CLKREQ# index.
+
+  @param[in]  ClkreqIndex       CLKREQ# number
+
+  @return CLKREQ# pad.
+**/
+GPIO_PAD
+GpioGetClkreqPad (
+  IN     UINT32   ClkreqIndex
+  );
+
+/**
+  Enables CLKREQ# pad in native mode.
+
+  @param[in]  ClkreqIndex       CLKREQ# number
+
+  @return none
+**/
+VOID
+GpioEnableClkreq (
+  IN     UINT32   ClkreqIndex
+  );
+
+/**
+  This function sets PCHHOT pin into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnablePchHot (
+  VOID
+  );
+
+/**
+  This function sets VRALERTB pin into native mode
+
+  @param[in]  none
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableVrAlert (
+  VOID
+  );
+
+/**
+  This function sets CPU GP pins into native mode
+
+  @param[in]  CpuGpPinNum               CPU GP pin number
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableCpuGpPin (
+  IN  UINT32                            CpuGpPinNum
+  );
+
+/**
+This function sets CPU C10 Gate pins into native mode
+
+@retval Status
+**/
+EFI_STATUS
+GpioEnableCpuC10GatePin (
+  VOID
+  );
+
+//
+// DDPx pins
+//
+typedef enum {
+  GpioDdp1 = 0x01,
+  GpioDdp2 = 0x02,
+  GpioDdp3 = 0x03,
+  GpioDdp4 = 0x04,
+  GpioDdpA = 0x10,
+  GpioDdpB = 0x11,
+  GpioDdpC = 0x12,
+  GpioDdpD = 0x13,
+  GpioDdpF = 0x15,
+} GPIO_DDP;
+
+/**
+  This function sets DDP pins into native mode
+
+  @param[in]  DdpInterface   DDPx interface
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableDpInterface (
+  IN  GPIO_DDP            DdpInterface
+  );
+
+//
+// DDI Port TBT_LSX interface
+//
+typedef enum {
+  GpioTbtLsxDdi1,
+  GpioTbtLsxDdi2,
+  GpioTbtLsxDdi3,
+  GpioTbtLsxDdi4,
+  GpioTbtLsxDdi5,
+  GpioTbtLsxDdi6
+} GPIO_TBT_LSX;
+
+/**
+  This function sets TBT_LSx pin into native mode
+
+  @param[in]  TbtLsxDdiPort     TBT_LSx DDI Port Number
+
+  @retval     Status
+**/
+EFI_STATUS
+GpioEnableTbtLsxInterface (
+  IN GPIO_TBT_LSX  TbtLsxDdiPort
+  );
+
+/**
+  This function configures GPIO connection between CNVi and CRF
+
+  @retval Status
+**/
+EFI_STATUS
+GpioConfigureCnviCrfConnection (
+  VOID
+  );
+
+/**
+  This function sets CNVi Bluetooth Enable value
+
+  @param[in] Value                CNVi BT enable value
+                                  0: Disable, 1: Enable
+  @retval Status
+**/
+EFI_STATUS
+GpioSetCnviBtEnState (
+   IN  UINT32  Value
+  );
+
+/**
+  This function sets CNVi Bluetooth Wireless Charging support
+
+  @param[in] BtWirelessCharging   CNVi BT Wireless Charging support
+                                  0: Normal BT operation (no Wireless Charging support)
+                                  1: Enable BT Wireless Charging
+  @retval Status
+**/
+EFI_STATUS
+GpioSetCnviBtWirelessCharging (
+  IN  UINT32  BtWirelessCharging
+  );
+
+/**
+  This function enables and configures CNVi Bluetooth Host wake-up interrupt
+
+  @param[in] None
+
+  @retval Status
+**/
+EFI_STATUS
+GpioConfigureCnviBtHostWakeInt (
+  VOID
+  );
+
+/**
+  This function enables IMGU CLKOUT native pin
+
+  @param[in] ImguClkOutPinIndex    The index of IMGU CLKOUT natine pin
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableImguClkOut (
+  IN UINT8 ImguClkOutPinIndex
+  );
+
+/**
+  Power button debounce configuration
+  Debounce time can be specified in microseconds. Only certain values according
+  to below formula are supported:
+   DebounceTime = (2 ^ PADCFG_DW2.DEBOUNCE)*(glitch filter clock period).
+  RTC clock with f = 32 KHz is used for glitch filter.
+   DebounceTime = (2 ^ PADCFG_DW2.DEBOUNCE)*(31.25 us).
+  Supported DebounceTime values are following:
+   DebounceTime = 0 -> Debounce feature disabled
+   DebounceTime > 0 && < 250us -> Not supported
+   DebounceTime = 250us - 1024000us -> Supported range (DebounceTime = 250us * 2^n)
+  For values not supported by HW, they will be rounded down to closest supported one
+
+  @param[in] DebounceTime    Debounce Time in microseconds
+                             If Debounce Time = 0, Debouncer feature will be disabled
+                             Function will set DebounceTime argument to rounded supported value
+**/
+VOID
+GpioSetPwrBtnDebounceTimer (
+  IN UINT32                DebounceTime
+  );
+
+
+/**
+  VCCIO level selection
+**/
+typedef enum {
+  GpioVcc3v3,
+  GpioVcc1v8,
+  MaxVccioSel
+} GPIO_VCCIO_SEL;
+/**
+  The function sets VCCIOSEL
+
+  @param[in]  GpioPad             GPIO pad
+  @param[in]  VccioSel            Pad voltage
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_UNSUPPORTED         The Pin is owned by others
+  @retval EFI_INVALID_PARAMETER   Invalid group or parameter
+**/
+EFI_STATUS
+GpioSetVccLevel (
+  IN  GPIO_PAD        GpioPad,
+  IN  GPIO_VCCIO_SEL  VccioSel
+  );
+
+/**
+  SBU (Sideband use) pins are used as auxiliary signals for Type C connector,
+  which are hard-wired to BSSB_LS natively for debug function.
+  when USB-C is enablde and debug not needed, disable pins (BSSB) used for debug through TypeC connector,
+  program SBU pins to high-Z/open circuit per USB-C spec.
+
+  @param[in]  UsbTcPortEnBitmap   USB Type C port enabled bitmap
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_UNSUPPORTED         SBU pads are not supported
+  @retval EFI_INVALID_PARAMETER   Invalid input parameter
+**/
+EFI_STATUS
+GpioDisableTypeCSbuDebug (
+  IN UINT32           UsbTcPortEnBitmap
+  );
+
+/**
+  When 2-wire DCI OOB is connected via SBU from Type C port, need set IO Standby state to masked (to operate as if no standby signal asserted)
+  to remain connection in low power state.
+
+  @param[in] DciPortId            DCI connection port ID
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_UNSUPPORTED         SBU pads are not supported
+  @retval EFI_INVALID_PARAMETER   Invalid input parameter
+**/
+EFI_STATUS
+Gpio2WireDciOobSetting (
+  IN UINT8                        DciPortId
+  );
+
+/**
+  This function enables the virtual wire msg bus from GPIO controller
+  to FIA. The virtual wire is used to transfer CLKREQ assert/de-assert
+  msg for CPU PCIe ports. Each of the PCIe ports has its dedicated VW
+  msg.
+
+  @param[in] PortIndex            Index of the CPU PCIe port for which VW
+                                  should be enabled.
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_UNSUPPORTED         Failed to set native mode.
+**/
+EFI_STATUS
+GpioEnableCpuPcieVwClkReqMsgBus (
+  IN UINT32  PortIndex
+  );
+
+/**
+  This function sets Time Sync Gpio into native mode
+
+  @param[in]  Index       index
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableTimeSync (
+  IN UINT32  Index
+  );
+
+/**
+  This function sets Tsn into native mode
+
+  @retval Status
+**/
+EFI_STATUS
+GpioEnableTsn (
+  VOID
+  );
+
+/**
+  This function is to be used In GpioLockPads() to override a lock request by SOC code.
+
+  @param[in]  Group          GPIO group
+  @param[in]  DwNum          Register number for current group (parameter applicable in accessing whole register).
+                             For group which has less then 32 pads per group DwNum must be 0.
+  @param[out] *UnlockCfgPad  DWORD bitmask for pads which are going to be left unlocked
+                             Bit position - PadNumber
+                             Bit value - 0: to be locked, 1: Leave unlocked
+  @param[out] *UnlockTxPad   DWORD bitmask for pads which are going to be left unlocked
+                             Bit position - PadNumber
+                             Bit value - 0: to be locked, 1: Leave unlocked
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid input parameter
+**/
+EFI_STATUS
+GpioUnlockOverride (
+  IN  GPIO_GROUP  Group,
+  IN  UINT32      DwNum,
+  OUT UINT32      *UnlockCfgPad,
+  OUT UINT32      *UnlockTxPad
+  );
+
+/**
+  Check if 0x13 opcode supported for writing to GPIO lock unlock register
+
+  @retval TRUE                It's supported
+  @retval FALSE               It's not supported
+**/
+BOOLEAN
+IsGpioLockOpcodeSupported (
+  VOID
+  );
+
+/**
+  Configures IO standby related settings for the GPIO pad.
+
+  @param[in]  GpioPad             GPIO pad
+  @param[in]  IoStandbyState      GPIO pad IO Standby state
+  @param[in]  IoStandbyTerm       GPIO pad IO Standby termination
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioConfigurePadIoStandby (
+  IN GPIO_PAD              GpioPad,
+  IN GPIO_IOSTANDBY_STATE  IoStandbyState,
+  IN GPIO_IOSTANDBY_TERM   IoStandbyTerm
+  );
+
+/**
+  Checks if GPIO PinMux corresponds to I2C4 B
+
+  @param[in] SdaPinMux    GPIO pad pinmux for SDA
+  @param[in] SclPinMux    GPIO pad pinmux for SCL
+
+  @retval TRUE         PinMux corresponds to I2C4 B
+          FALSE        PinMux equals to I2C4 A
+**/
+EFI_STATUS
+GpioIsSerialIoI2c4bMuxed (
+  IN UINT32  SdaPinMux,
+  IN UINT32  SclPinMux
+  );
+
+#endif // _GPIO_PRIVATE_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.c
new file mode 100644
index 0000000000..5a6360931b
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.c
@@ -0,0 +1,140 @@
+/** @file
+  Implementation of BaseGpioCheckConflictLib.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/GpioCheckConflictLib.h>
+#include <Uefi/UefiMultiPhase.h>
+#include <Pi/PiBootMode.h>
+#include <Pi/PiHob.h>
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/GpioPrivateLib.h>
+
+/**
+  Check Gpio PadMode conflict and report it.
+
+  @retval     none.
+**/
+VOID
+GpioCheckConflict (
+  VOID
+  )
+{
+  EFI_HOB_GUID_TYPE              *GpioCheckConflictHob;
+  GPIO_PAD_MODE_INFO             *GpioCheckConflictHobData;
+  UINT32                          HobDataSize;
+  UINT32                          GpioCount;
+  UINT32                          GpioIndex;
+  GPIO_CONFIG                     GpioActualConfig;
+
+  GpioCheckConflictHob = NULL;
+  GpioCheckConflictHobData = NULL;
+
+  DEBUG ((DEBUG_INFO, "GpioCheckConflict Start..\n"));
+
+  //
+  // Use Guid to find HOB.
+  //
+  GpioCheckConflictHob = (EFI_HOB_GUID_TYPE *) GetFirstGuidHob (&gGpioCheckConflictHobGuid);
+  if (GpioCheckConflictHob == NULL) {
+    DEBUG ((DEBUG_INFO, "[GPIO Conflict Check] No GPIO HOB found.\n"));
+  } else {
+    while (GpioCheckConflictHob != NULL) {
+      //
+      // Find the Data area pointer and Data size from the Hob
+      //
+      GpioCheckConflictHobData = (GPIO_PAD_MODE_INFO *) GET_GUID_HOB_DATA (GpioCheckConflictHob);
+      HobDataSize = GET_GUID_HOB_DATA_SIZE (GpioCheckConflictHob);
+
+      GpioCount = HobDataSize / sizeof (GPIO_PAD_MODE_INFO);
+      DEBUG ((DEBUG_INFO, "[GPIO Conflict Check] Hob : GpioCount =  %d\n", GpioCount));
+
+      //
+      // Probe Gpio entries in Hob and compare which are conflicted
+      //
+      for (GpioIndex = 0; GpioIndex < GpioCount ; GpioIndex++) {
+        GpioGetPadConfig (GpioCheckConflictHobData[GpioIndex].GpioPad, &GpioActualConfig);
+        if (GpioCheckConflictHobData[GpioIndex].GpioPadMode != GpioActualConfig.PadMode) {
+          DEBUG ((DEBUG_ERROR, "[GPIO Conflict Check] Identified conflict on pad %a (actual: 0x%X, expected: 0x%X)\n",
+                  GpioName (GpioCheckConflictHobData[GpioIndex].GpioPad),
+                  GpioActualConfig.PadMode,
+                  GpioCheckConflictHobData[GpioIndex].GpioPadMode));
+        }
+      }
+      //
+      // Find next Hob and return the Hob pointer by the specific Hob Guid
+      //
+      GpioCheckConflictHob = GET_NEXT_HOB (GpioCheckConflictHob);
+      GpioCheckConflictHob = GetNextGuidHob (&gGpioCheckConflictHobGuid, GpioCheckConflictHob);
+    }
+
+    DEBUG ((DEBUG_INFO, "GpioCheckConflict End.\n"));
+  }
+
+  return;
+}
+
+/**
+  This libaray will create one Hob for each Gpio config table
+  without PadMode is GpioHardwareDefault
+
+  @param[in]  GpioDefinition    Point to Platform Gpio table
+  @param[in]  GpioTableCount    Number of Gpio table entries
+
+  @retval     none.
+**/
+VOID
+CreateGpioCheckConflictHob (
+  IN GPIO_INIT_CONFIG          *GpioDefinition,
+  IN UINT32                    GpioTableCount
+  )
+{
+
+  UINT32                   Index;
+  UINT32                   GpioIndex;
+  GPIO_PAD_MODE_INFO       *GpioCheckConflictHobData;
+  UINT16                   GpioCount;
+
+  GpioCount = 0;
+  GpioIndex = 0;
+
+  DEBUG ((DEBUG_INFO, "CreateGpioCheckConflictHob Start \n"));
+
+  for (Index = 0; Index < GpioTableCount ; Index++) {
+    if (GpioDefinition[Index].GpioConfig.PadMode == GpioHardwareDefault) {
+      continue;
+    } else {
+      //
+      // Calculate non-default GPIO number
+      //
+      GpioCount++;
+    }
+  }
+
+  //
+  // Build a HOB tagged with a GUID for identification and returns
+  // the start address of GUID HOB data.
+  //
+  GpioCheckConflictHobData = (GPIO_PAD_MODE_INFO *) BuildGuidHob (&gGpioCheckConflictHobGuid , GpioCount * sizeof (GPIO_PAD_MODE_INFO));
+
+  //
+  // Record Non Default Gpio entries to the Hob
+  //
+  for (Index = 0; Index < GpioTableCount; Index++) {
+    if (GpioDefinition[Index].GpioConfig.PadMode == GpioHardwareDefault) {
+      continue;
+    } else {
+      if (GpioCheckConflictHobData != NULL) {
+        GpioCheckConflictHobData[GpioIndex].GpioPad = GpioDefinition[Index].GpioPad;
+        GpioCheckConflictHobData[GpioIndex].GpioPadMode = GpioDefinition[Index].GpioConfig.PadMode;
+        GpioIndex++;
+      }
+    }
+  }
+
+  DEBUG ((DEBUG_INFO, "CreateGpioCheckConflictHob End \n"));
+  return;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.inf
new file mode 100644
index 0000000000..f7e1de774d
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.inf
@@ -0,0 +1,29 @@
+## @file
+#  Component information file for BaseGpioCheckConflictLib.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = BaseGpioCheckConflictLib
+  FILE_GUID                      = C19A848A-F013-4DBF-9C23-F0F74DEA6F14
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = GpioCheckConflictLib
+
+[LibraryClasses]
+  DebugLib
+  HobLib
+  GpioLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  TigerlakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  BaseGpioCheckConflictLib.c
+
+[Guids]
+  gGpioCheckConflictHobGuid
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.c
new file mode 100644
index 0000000000..2f83f95b27
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.c
@@ -0,0 +1,35 @@
+/** @file
+  Implementation of BaseGpioCheckConflicLibNull.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/GpioCheckConflictLib.h>
+
+/**
+  Check Gpio PadMode conflict and report it.
+**/
+VOID
+GpioCheckConflict (
+  VOID
+  )
+{
+  return;
+}
+
+/**
+  This libaray will create one Hob for each Gpio config table
+  without PadMode is GpioHardwareDefault
+
+  @param[in]  GpioDefinition    Point to Platform Gpio table
+  @param[in]  GpioTableCount    Number of Gpio table entries
+**/
+VOID
+CreateGpioCheckConflictHob (
+  IN GPIO_INIT_CONFIG          *GpioDefinition,
+  IN UINT32                    GpioTableCount
+  )
+{
+  return;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf
new file mode 100644
index 0000000000..1c226d7c16
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf
@@ -0,0 +1,26 @@
+## @file
+#  Component information file for BaseGpioCheckConflictLib.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = BaseGpioCheckConflictLibNull
+  FILE_GUID                      = C19A848A-F013-4DBF-9C23-F0F74DEA6F14
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = GpioCheckConflictLib
+
+[LibraryClasses]
+  DebugLib
+  HobLib
+  GpioLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  TigerlakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  BaseGpioCheckConflictLibNull.c
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioInit.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioInit.c
new file mode 100644
index 0000000000..99dbbf0ca6
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioInit.c
@@ -0,0 +1,558 @@
+/** @file
+  This file contains routines for GPIO initialization
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "GpioLibrary.h"
+#include <Register/PchPcrRegs.h>
+#include <Library/GpioCheckConflictLib.h>
+
+//
+// GPIO_GROUP_DW_DATA structure is used by GpioConfigurePch function
+// to cache values which will be programmed into respective GPIO registers
+// after all GpioPads are processed. This way MMIO accesses are decreased
+// and instead of doing one programming for one GpioPad there is only
+// one access for whole register.
+//
+typedef struct {
+  UINT32             HostSoftOwnReg;
+  UINT32             HostSoftOwnRegMask;
+  UINT32             GpiGpeEnReg;
+  UINT32             GpiGpeEnRegMask;
+  UINT32             GpiNmiEnReg;
+  UINT32             GpiNmiEnRegMask;
+  UINT32             GpiSmiEnReg;
+  UINT32             GpiSmiEnRegMask;
+  UINT32             ConfigUnlockMask;
+  UINT32             OutputUnlockMask;
+} GPIO_GROUP_DW_DATA;
+
+//
+// GPIO_GROUP_DW_NUMBER contains number of DWords required to
+// store Pad data for all groups. Each pad uses one bit.
+//
+#define GPIO_GROUP_DW_NUMBER  1
+
+/**
+  Get GPIO DW Register values (HOSTSW_OWN, GPE_EN, NMI_EN, Lock).
+
+  @param[in]     PadNumber      GPIO pad number
+  @param[in]     GpioConfig     GPIO Config data
+  @param[in out] DwRegsValues   Values for GPIO DW Registers
+
+  @retval None
+**/
+STATIC
+VOID
+GpioDwRegValueFromGpioConfig (
+  IN UINT32                 PadNumber,
+  IN CONST GPIO_CONFIG      *GpioConfig,
+  IN OUT GPIO_GROUP_DW_DATA *GroupDwData
+  )
+{
+  UINT32  PadBitPosition;
+  UINT32  DwNum;
+
+  PadBitPosition = GPIO_GET_PAD_POSITION (PadNumber);
+  DwNum = GPIO_GET_DW_NUM (PadNumber);
+
+  if (DwNum >= GPIO_GROUP_DW_NUMBER) {
+    ASSERT (FALSE);
+    return;
+  }
+  //
+  // Update value to be programmed in HOSTSW_OWN register
+  //
+  GroupDwData[DwNum].HostSoftOwnRegMask |= (GpioConfig->HostSoftPadOwn & 0x1) << PadBitPosition;
+  GroupDwData[DwNum].HostSoftOwnReg |= (GpioConfig->HostSoftPadOwn >> 0x1) << PadBitPosition;
+
+  //
+  // Update value to be programmed in GPI_GPE_EN register
+  //
+  GroupDwData[DwNum].GpiGpeEnRegMask |= (GpioConfig->InterruptConfig & 0x1) << PadBitPosition;
+  GroupDwData[DwNum].GpiGpeEnReg |= ((GpioConfig->InterruptConfig & GpioIntSci) >> 3) << PadBitPosition;
+
+  //
+  // Update value to be programmed in GPI_NMI_EN register
+  //
+  GroupDwData[DwNum].GpiNmiEnRegMask |= (GpioConfig->InterruptConfig & 0x1) << PadBitPosition;
+  GroupDwData[DwNum].GpiNmiEnReg |= ((GpioConfig->InterruptConfig & GpioIntNmi) >> 1) << PadBitPosition;
+
+  //
+  // Update value to be programmed in GPI_SMI_EN register
+  GroupDwData[DwNum].GpiSmiEnRegMask |= (GpioConfig->InterruptConfig & 0x1) << PadBitPosition;
+  GroupDwData[DwNum].GpiSmiEnReg |= ((GpioConfig->InterruptConfig & GpioIntSmi) >> 2) << PadBitPosition;
+  if ((GpioConfig->InterruptConfig & GpioIntSmi) == GpioIntSmi) {
+    GroupDwData[DwNum].HostSoftOwnRegMask |= 1 << PadBitPosition;
+    GroupDwData[DwNum].HostSoftOwnReg |= 1 << PadBitPosition;
+  }
+
+  //
+  // Update information on Pad Configuration Lock
+  //
+  GroupDwData[DwNum].ConfigUnlockMask |= ((GpioConfig->LockConfig >> 1) & 0x1) << PadBitPosition;
+
+  //
+  // Update information on Pad Configuration Lock Tx
+  //
+  GroupDwData[DwNum].OutputUnlockMask |= ((GpioConfig->LockConfig >> 3) & 0x1) << PadBitPosition;
+
+  //
+  // if pad in GpioMode is an output default action should be to leave output unlocked
+  //
+  if ((GpioConfig->PadMode == GpioPadModeGpio) &&
+      (GpioConfig->Direction == GpioDirOut) &&
+      ((GpioConfig->LockConfig & B_GPIO_LOCK_CONFIG_OUTPUT_LOCK_MASK) == GpioLockDefault)) {
+    GroupDwData[DwNum].OutputUnlockMask |= 0x1 << PadBitPosition;
+  }
+}
+
+/**
+  This internal procedure will scan GPIO initialization table and unlock
+  all pads present in it
+
+  @param[in] NumberOfItem               Number of GPIO pad records in table
+  @param[in] GpioInitTableAddress       GPIO initialization table
+  @param[in] Index                      Index of GPIO Initialization table record
+
+  @retval EFI_SUCCESS                   The function completed successfully
+  @retval EFI_INVALID_PARAMETER         Invalid group or pad number
+**/
+STATIC
+EFI_STATUS
+GpioUnlockPadsForAGroup (
+  IN UINT32                    NumberOfItems,
+  IN GPIO_INIT_CONFIG          *GpioInitTableAddress,
+  IN UINT32                    Index
+  )
+{
+  UINT32                 PadsToUnlock[GPIO_GROUP_DW_NUMBER];
+  UINT32                 DwNum;
+  UINT32                 PadBitPosition;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+  CONST GPIO_INIT_CONFIG *GpioData;
+  GPIO_GROUP             Group;
+  UINT32                 GroupIndex;
+  UINT32                 PadNumber;
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  GpioData   = &GpioInitTableAddress[Index];
+  Group      = GpioGetGroupFromGpioPad (GpioData->GpioPad);
+  GroupIndex = GpioGetGroupIndexFromGpioPad (GpioData->GpioPad);
+
+  ZeroMem (PadsToUnlock, sizeof (PadsToUnlock));
+  //
+  // Loop through pads for one group. If pad belongs to a different group then
+  // break and move to register programming.
+  //
+  while (Index < NumberOfItems) {
+
+    GpioData   = &GpioInitTableAddress[Index];
+    if (GroupIndex != GpioGetGroupIndexFromGpioPad (GpioData->GpioPad)) {
+      //if next pad is from different group then break loop
+      break;
+    }
+
+    PadNumber  = GpioGetPadNumberFromGpioPad (GpioData->GpioPad);
+    //
+    // Check if legal pin number
+    //
+    if (PadNumber >= GpioGroupInfo[GroupIndex].PadPerGroup) {
+      DEBUG ((DEBUG_ERROR, "GPIO ERROR: Pin number (%d) exceeds possible range for group %d\n", PadNumber, GroupIndex));
+      return EFI_INVALID_PARAMETER;
+    }
+
+    PadBitPosition = GPIO_GET_PAD_POSITION (PadNumber);
+    DwNum = GPIO_GET_DW_NUM (PadNumber);
+
+    if (DwNum >= GPIO_GROUP_DW_NUMBER) {
+      ASSERT (FALSE);
+      return EFI_UNSUPPORTED;
+    }
+    //
+    // Update pads which need to be unlocked
+    //
+    PadsToUnlock[DwNum] |= 0x1 << PadBitPosition;
+
+    //Move to next item
+    Index++;
+  }
+
+  for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) {
+    //
+    // Unlock pads
+    //
+    if (PadsToUnlock[DwNum] != 0) {
+      GpioUnlockPadCfgForGroupDw (Group, DwNum, PadsToUnlock[DwNum]);
+      GpioUnlockPadCfgTxForGroupDw (Group, DwNum, PadsToUnlock[DwNum]);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will initialize multiple PCH GPIO pins
+
+  @param[in] NumberofItem               Number of GPIO pads to be updated
+  @param[in] GpioInitTableAddress       GPIO initialization table
+
+  @retval EFI_SUCCESS                   The function completed successfully
+  @retval EFI_INVALID_PARAMETER         Invalid group or pad number
+**/
+STATIC
+EFI_STATUS
+GpioConfigurePch (
+  IN UINT32                    NumberOfItems,
+  IN GPIO_INIT_CONFIG          *GpioInitTableAddress
+  )
+{
+  UINT32                 Index;
+  UINT32                 PadCfgDwReg[GPIO_PADCFG_DW_REG_NUMBER];
+  UINT32                 PadCfgDwRegMask[GPIO_PADCFG_DW_REG_NUMBER];
+  UINT32                 PadCfgReg;
+  GPIO_GROUP_DW_DATA     GroupDwData[GPIO_GROUP_DW_NUMBER];
+  UINT32                 DwNum;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+  GPIO_PAD_OWN           PadOwnVal;
+  CONST GPIO_INIT_CONFIG *GpioData;
+  UINT32                 GroupIndex;
+  UINT32                 PadNumber;
+  PCH_SBI_PID            GpioCom;
+
+  PadOwnVal = GpioPadOwnHost;
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  Index = 0;
+  while (Index < NumberOfItems) {
+
+    GpioData   = &GpioInitTableAddress[Index];
+    GroupIndex = GpioGetGroupIndexFromGpioPad (GpioData->GpioPad);
+    GpioCom    = GpioGroupInfo[GroupIndex].Community;
+
+    DEBUG_CODE_BEGIN();
+    if (!GpioIsCorrectPadForThisChipset (GpioData->GpioPad)) {
+      DEBUG ((DEBUG_ERROR, "GPIO ERROR: Incorrect GpioPad (0x%08x) used on this chipset!\n", GpioData->GpioPad));
+      ASSERT (FALSE);
+      return EFI_UNSUPPORTED;
+    }
+    DEBUG_CODE_END ();
+
+    //
+    // Unlock pads for a given group which are going to be reconfigured
+    //
+    //
+    // Because PADCFGLOCK/LOCKTX register reset domain is Powergood, lock settings
+    // will get back to default only after G3 or DeepSx transition. On the other hand GpioPads
+    // configuration is controlled by a configurable type of reset - PadRstCfg. This means that if
+    // PadRstCfg != Powergood GpioPad will have its configuration locked despite it being not the
+    // one desired by BIOS. Before reconfiguring all pads they will get unlocked.
+    //
+    GpioUnlockPadsForAGroup (NumberOfItems, GpioInitTableAddress, Index);
+
+    ZeroMem (GroupDwData, sizeof (GroupDwData));
+    //
+    // Loop through pads for one group. If pad belongs to a different group then
+    // break and move to register programming.
+    //
+    while (Index < NumberOfItems) {
+
+      GpioData   = &GpioInitTableAddress[Index];
+      if (GroupIndex != GpioGetGroupIndexFromGpioPad (GpioData->GpioPad)) {
+        //if next pad is from different group then break loop
+        break;
+      }
+
+      PadNumber  = GpioGetPadNumberFromGpioPad (GpioData->GpioPad);
+
+      DEBUG_CODE_BEGIN ();
+      //
+      // Check if legal pin number
+      //
+      if (PadNumber >= GpioGroupInfo[GroupIndex].PadPerGroup) {
+        DEBUG ((DEBUG_ERROR, "GPIO ERROR: Pin number (%d) exceeds possible range for group %d\n", PadNumber, GroupIndex));
+        return EFI_INVALID_PARAMETER;
+      }
+
+      //
+      // Check if selected GPIO Pad is not owned by CSME/ISH
+      //
+      GpioGetPadOwnership (GpioData->GpioPad, &PadOwnVal);
+
+      if (PadOwnVal != GpioPadOwnHost) {
+        DEBUG ((DEBUG_ERROR, "GPIO ERROR: Accessing pad not owned by host (Group=%d, Pad=%d)!\n", GroupIndex, PadNumber));
+        DEBUG ((DEBUG_ERROR, "** Please make sure the GPIO usage in sync between CSME and BIOS configuration. \n"));
+        DEBUG ((DEBUG_ERROR, "** All the GPIO occupied by CSME should not do any configuration by BIOS.\n"));
+        //Move to next item
+        Index++;
+        continue;
+      }
+
+      //
+      // Check if Pad enabled for SCI is to be in unlocked state
+      //
+      if (((GpioData->GpioConfig.InterruptConfig & GpioIntSci) == GpioIntSci) &&
+          ((GpioData->GpioConfig.LockConfig & B_GPIO_LOCK_CONFIG_PAD_CONF_LOCK_MASK) != GpioPadConfigUnlock)){
+        DEBUG ((DEBUG_ERROR, "GPIO ERROR: %a used for SCI is not unlocked!\n", GpioName (GpioData->GpioPad)));
+        ASSERT (FALSE);
+        return EFI_INVALID_PARAMETER;
+      }
+      DEBUG_CODE_END ();
+
+      ZeroMem (PadCfgDwReg, sizeof (PadCfgDwReg));
+      ZeroMem (PadCfgDwRegMask, sizeof (PadCfgDwRegMask));
+      //
+      // Get GPIO PADCFG register value from GPIO config data
+      //
+      GpioPadCfgRegValueFromGpioConfig (
+        GpioData->GpioPad,
+        &GpioData->GpioConfig,
+        PadCfgDwReg,
+        PadCfgDwRegMask
+        );
+
+      //
+      // Create PADCFG register offset using group and pad number
+      //
+      PadCfgReg = S_GPIO_PCR_PADCFG * PadNumber + GpioGroupInfo[GroupIndex].PadCfgOffset;
+
+      //
+      // Write PADCFG DW0 register
+      //
+      MmioAndThenOr32 (
+        PCH_PCR_ADDRESS (GpioCom, PadCfgReg),
+        ~PadCfgDwRegMask[0],
+        PadCfgDwReg[0]
+        );
+      //
+      // Write PADCFG DW1 register
+      //
+      MmioAndThenOr32 (
+        PCH_PCR_ADDRESS (GpioCom, PadCfgReg + 0x4),
+        ~PadCfgDwRegMask[1],
+        PadCfgDwReg[1]
+        );
+
+      //
+      // Write PADCFG DW2 register
+      //
+      MmioAndThenOr32 (
+        PCH_PCR_ADDRESS (GpioCom, PadCfgReg + 0x8),
+        ~PadCfgDwRegMask[2],
+        PadCfgDwReg[2]
+        );
+
+      //
+      // Get GPIO DW register values from GPIO config data
+      //
+      GpioDwRegValueFromGpioConfig (
+        PadNumber,
+        &GpioData->GpioConfig,
+        GroupDwData
+        );
+
+      //Move to next item
+      Index++;
+    }
+
+    for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) {
+      //
+      // Write HOSTSW_OWN registers
+      //
+      if (GpioGroupInfo[GroupIndex].HostOwnOffset != NO_REGISTER_FOR_PROPERTY) {
+        MmioAndThenOr32 (
+          PCH_PCR_ADDRESS (GpioCom, GpioGroupInfo[GroupIndex].HostOwnOffset + DwNum * 0x4),
+          ~GroupDwData[DwNum].HostSoftOwnRegMask,
+          GroupDwData[DwNum].HostSoftOwnReg
+          );
+      }
+
+      //
+      // Write GPI_GPE_EN registers
+      //
+      if (GpioGroupInfo[GroupIndex].GpiGpeEnOffset != NO_REGISTER_FOR_PROPERTY) {
+        MmioAndThenOr32 (
+          PCH_PCR_ADDRESS (GpioCom, GpioGroupInfo[GroupIndex].GpiGpeEnOffset + DwNum * 0x4),
+          ~GroupDwData[DwNum].GpiGpeEnRegMask,
+          GroupDwData[DwNum].GpiGpeEnReg
+          );
+      }
+
+      //
+      // Write GPI_NMI_EN registers
+      //
+      if (GpioGroupInfo[GroupIndex].NmiEnOffset != NO_REGISTER_FOR_PROPERTY) {
+        MmioAndThenOr32 (
+          PCH_PCR_ADDRESS (GpioCom, GpioGroupInfo[GroupIndex].NmiEnOffset + DwNum * 0x4),
+          ~GroupDwData[DwNum].GpiNmiEnRegMask,
+          GroupDwData[DwNum].GpiNmiEnReg
+          );
+      } else if (GroupDwData[DwNum].GpiNmiEnReg != 0x0) {
+        DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %d has no pads supporting NMI\n", GroupIndex));
+        ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
+      }
+
+      //
+      // Write GPI_SMI_EN registers
+      //
+      if (GpioGroupInfo[GroupIndex].SmiEnOffset != NO_REGISTER_FOR_PROPERTY) {
+        MmioAndThenOr32 (
+          PCH_PCR_ADDRESS (GpioCom, GpioGroupInfo[GroupIndex].SmiEnOffset + DwNum * 0x4),
+          ~GroupDwData[DwNum].GpiSmiEnRegMask,
+          GroupDwData[DwNum].GpiSmiEnReg
+          );
+      } else if (GroupDwData[DwNum].GpiSmiEnReg != 0x0) {
+        DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %d has no pads supporting SMI\n", GroupIndex));
+        ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
+      }
+
+      //
+      // Update Pad Configuration unlock data
+      //
+      if (GroupDwData[DwNum].ConfigUnlockMask) {
+        GpioStoreGroupDwUnlockPadConfigData (GroupIndex, DwNum, GroupDwData[DwNum].ConfigUnlockMask);
+      }
+
+      //
+      // Update Pad Output unlock data
+      //
+      if (GroupDwData[DwNum].OutputUnlockMask) {
+        GpioStoreGroupDwUnlockOutputData (GroupIndex, DwNum, GroupDwData[DwNum].OutputUnlockMask);
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will clear all status bits of any GPIO interrupts.
+
+  @param[in] none
+
+  @retval EFI_SUCCESS                   The function completed successfully
+  @retval EFI_INVALID_PARAMETER         Invalid group or pad number
+**/
+STATIC
+EFI_STATUS
+GpioClearAllGpioInterrupts (
+  VOID
+  )
+{
+  GPIO_GROUP             Group;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  GPIO_GROUP             GpioGroupLowest;
+  GPIO_GROUP             GpioGroupHighest;
+  UINT32                 GroupIndex;
+  UINT32                 GpioGroupInfoLength;
+  UINT32                 DwNum;
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  GpioGroupLowest = GpioGetLowestGroup ();
+  GpioGroupHighest = GpioGetHighestGroup ();
+
+  for (Group = GpioGroupLowest; Group <= GpioGroupHighest; Group++) {
+    GroupIndex = GpioGetGroupIndexFromGroup (Group);
+    //
+    // Check if group has GPI IS register
+    //
+    if (GpioGroupInfo[GroupIndex].GpiIsOffset != NO_REGISTER_FOR_PROPERTY) {
+      //
+      // Clear all GPI_IS Status bits by writing '1'
+      //
+      for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) {
+        MmioWrite32 (
+          PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, GpioGroupInfo[GroupIndex].GpiIsOffset + DwNum * 0x4),
+          0xFFFFFFFF
+          );
+      }
+    }
+
+    //
+    // Check if group has GPI_GPE_STS register
+    //
+    if (GpioGroupInfo[GroupIndex].GpiGpeStsOffset != NO_REGISTER_FOR_PROPERTY) {
+      //
+      // Clear all GPI_GPE_STS Status bits by writing '1'
+      //
+      for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) {
+        MmioWrite32 (
+          PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, GpioGroupInfo[GroupIndex].GpiGpeStsOffset + DwNum * 0x4),
+          0xFFFFFFFF
+          );
+      }
+    }
+
+    //
+    // Check if group has SMI_STS register
+    //
+    if (GpioGroupInfo[GroupIndex].SmiStsOffset != NO_REGISTER_FOR_PROPERTY) {
+      //
+      // Clear all SMI_STS Status bits by writing '1'
+      //
+      for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) {
+        MmioWrite32 (
+          PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, GpioGroupInfo[GroupIndex].SmiStsOffset + DwNum * 4),
+          0xFFFFFFFF
+          );
+      }
+    }
+
+    //
+    // Check if group has NMI_STS register
+    //
+    if (GpioGroupInfo[GroupIndex].NmiStsOffset != NO_REGISTER_FOR_PROPERTY) {
+      //
+      // Clear all NMI_STS Status bits by writing '1'
+      //
+      for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) {
+        MmioWrite32 (
+          PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, GpioGroupInfo[GroupIndex].NmiStsOffset + DwNum * 4),
+          0xFFFFFFFF
+          );
+      }
+    }
+
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will initialize multiple GPIO pins. Use GPIO_INIT_CONFIG structure.
+  Structure contains fields that can be used to configure each pad.
+  Pad not configured using GPIO_INIT_CONFIG will be left with hardware default values.
+  Separate fields could be set to hardware default if it does not matter, except
+  GpioPad and PadMode.
+  Function will work in most efficient way if pads which belong to the same group are
+  placed in adjacent records of the table.
+  Although function can enable pads for Native mode, such programming is done
+  by reference code when enabling related silicon feature.
+
+  @param[in] NumberofItem               Number of GPIO pads to be updated
+  @param[in] GpioInitTableAddress       GPIO initialization table
+
+  @retval EFI_SUCCESS                   The function completed successfully
+  @retval EFI_INVALID_PARAMETER         Invalid group or pad number
+**/
+EFI_STATUS
+GpioConfigurePads (
+  IN UINT32                    NumberOfItems,
+  IN GPIO_INIT_CONFIG          *GpioInitTableAddress
+  )
+{
+  EFI_STATUS   Status;
+
+  Status =  GpioConfigurePch (NumberOfItems, GpioInitTableAddress);
+
+  CreateGpioCheckConflictHob (GpioInitTableAddress, NumberOfItems);
+
+  GpioClearAllGpioInterrupts ();
+  return Status;
+}
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioLib.c
new file mode 100644
index 0000000000..d6c13fe581
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioLib.c
@@ -0,0 +1,2387 @@
+/** @file
+  This file contains routines for GPIO
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "GpioLibrary.h"
+#include <Register/PchPcrRegs.h>
+
+/**
+  This procedure will check if GpioGroup argument is correct and
+  supplied DW reg number can be used for this group to access DW registers.
+  Function will check below conditions:
+   - Valid GpioGroup
+   - DwNum is has valid value for this group
+
+  @param[in] Group        GPIO group
+  @param[in] DwNum        Register number for current group (parameter applicable in accessing whole register).
+                          For group which has less then 32 pads per group DwNum must be 0.
+
+  @retval TRUE             DW Reg number and GpioGroup is valid
+  @retval FALSE            DW Reg number and GpioGroup is invalid
+**/
+STATIC
+BOOLEAN
+GpioIsGroupAndDwNumValid (
+  IN GPIO_GROUP             Group,
+  IN UINT32                 DwNum
+  )
+{
+  UINT32                 GroupIndex;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  GroupIndex = GpioGetGroupIndexFromGroup (Group);
+
+  if ((Group < GpioGetLowestGroup ()) || (Group > GpioGetHighestGroup ()) || (GroupIndex >= GpioGroupInfoLength)) {
+    DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group argument (%d) is not within range of possible groups for this PCH\n", GroupIndex));
+    goto Error;
+  }
+
+  //
+  // Check if DwNum argument does not exceed number of DWord registers
+  // resulting from available pads for certain group
+  //
+  if (DwNum > GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex].PadPerGroup - 1)){
+    goto Error;
+  }
+
+  return TRUE;
+Error:
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+//
+// Possible registers to be accessed using GpioReadReg()/GpioWriteReg() functions
+//
+typedef enum {
+  GpioHostOwnershipRegister = 0,
+  GpioGpeEnableRegister,
+  GpioGpeStatusRegister,
+  GpioSmiEnableRegister,
+  GpioSmiStatusRegister,
+  GpioNmiEnableRegister,
+  GpioPadConfigLockRegister,
+  GpioPadLockOutputRegister
+} GPIO_REG;
+
+/**
+  This procedure will read GPIO register
+
+  @param[in] RegType              GPIO register type
+  @param[in] Group                GPIO group
+  @param[in] DwNum                Register number for current group (parameter applicable in accessing whole register).
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[out] ReadVal             Read data
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_UNSUPPORTED         Feature is not supported for this group or pad
+**/
+STATIC
+EFI_STATUS
+GpioReadReg (
+  IN GPIO_REG               RegType,
+  IN GPIO_GROUP             Group,
+  IN UINT32                 DwNum,
+  OUT UINT32                *ReadVal
+  )
+{
+  UINT32                 RegOffset;
+  UINT32                 GroupIndex;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+
+  RegOffset = NO_REGISTER_FOR_PROPERTY;
+  GroupIndex = GpioGetGroupIndexFromGroup (Group);
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  switch (RegType) {
+    case GpioHostOwnershipRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].HostOwnOffset;
+      break;
+    case GpioGpeEnableRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].GpiGpeEnOffset;
+      break;
+    case GpioGpeStatusRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].GpiGpeStsOffset;
+      break;
+    case GpioSmiEnableRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].SmiEnOffset;
+      break;
+    case GpioSmiStatusRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].SmiStsOffset;
+      break;
+    case GpioNmiEnableRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].NmiEnOffset;
+      break;
+    case GpioPadConfigLockRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].PadCfgLockOffset;
+      break;
+    case GpioPadLockOutputRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].PadCfgLockTxOffset;
+      break;
+    default:
+      break;
+  }
+
+  //
+  // Check if selected register exists
+  //
+  if (RegOffset == NO_REGISTER_FOR_PROPERTY) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // If there are more then 32 pads per group then certain
+  // group information would be split into more then one DWord register.
+  //
+  if ((RegType == GpioPadConfigLockRegister) || (RegType == GpioPadLockOutputRegister)) {
+    //
+    // PadConfigLock and OutputLock registers when used for group containing more than 32 pads
+    // are not placed in a continuous way, e.g:
+    // 0x0 - PadConfigLock_DW0
+    // 0x4 - OutputLock_DW0
+    // 0x8 - PadConfigLock_DW1
+    // 0xC - OutputLock_DW1
+    //
+    RegOffset += DwNum * 0x8;
+  } else {
+    RegOffset += DwNum * 0x4;
+  }
+
+  *ReadVal = MmioRead32 (PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, RegOffset));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will write GPIO register
+
+  @param[in] RegType              GPIO register type
+  @param[in] Group                GPIO group
+  @param[in] DwNum                Register number for current group (parameter applicable in accessing whole register).
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in] RegAndMask           Mask which will be AND'ed with register value
+  @param[in] RegOrMask            Mask which will be OR'ed with register value
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_UNSUPPORTED         Feature is not supported for this group or pad
+**/
+STATIC
+EFI_STATUS
+GpioWriteReg (
+  IN GPIO_REG               RegType,
+  IN GPIO_GROUP             Group,
+  IN UINT32                 DwNum,
+  IN UINT32                 RegAndMask,
+  IN UINT32                 RegOrMask
+  )
+{
+  UINT32                 RegOffset;
+  UINT32                 GroupIndex;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+  UINT32                 PadCfgLock;
+  BOOLEAN                Lockable;
+
+  Lockable = FALSE;
+  PadCfgLock = 0;
+  RegOffset = NO_REGISTER_FOR_PROPERTY;
+  GroupIndex = GpioGetGroupIndexFromGroup (Group);
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  switch (RegType) {
+    case GpioHostOwnershipRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].HostOwnOffset;
+      break;
+    case GpioGpeEnableRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].GpiGpeEnOffset;
+      Lockable = TRUE;
+      break;
+    case GpioGpeStatusRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].GpiGpeStsOffset;
+      break;
+    case GpioSmiEnableRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].SmiEnOffset;
+      Lockable = TRUE;
+      break;
+    case GpioSmiStatusRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].SmiStsOffset;
+      break;
+    case GpioNmiEnableRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].NmiEnOffset;
+      Lockable = TRUE;
+      break;
+    case GpioPadConfigLockRegister:
+    case GpioPadLockOutputRegister:
+    default:
+      break;
+  }
+
+  //
+  // Check if selected register exists
+  //
+  if (RegOffset == NO_REGISTER_FOR_PROPERTY) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (Lockable) {
+    GpioGetPadCfgLockForGroupDw (Group, DwNum, &PadCfgLock);
+    if (PadCfgLock) {
+      //
+      // Check if for pads which are going to be reconfigured lock is set.
+      //
+      if ((~RegAndMask | RegOrMask) & PadCfgLock) {
+        //
+        // Unlock all pads for this Group DW reg for simplicity
+        // even if not all of those pads will have their settings reprogrammed
+        //
+        GpioUnlockPadCfgForGroupDw (Group, DwNum, PadCfgLock);
+      } else {
+        //
+        // No need to perform an unlock as pads which are going to be reconfigured
+        // are not in locked state
+        //
+        PadCfgLock = 0;
+      }
+    }
+  }
+
+  //
+  // If there are more then 32 pads per group then certain
+  // group information would be split into more then one DWord register.
+  //
+  RegOffset += DwNum * 0x4;
+
+  MmioAndThenOr32 (
+    PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, RegOffset),
+    RegAndMask,
+    RegOrMask
+    );
+
+  if (Lockable && PadCfgLock) {
+    //
+    // Lock previously unlocked pads
+    //
+    GpioLockPadCfgForGroupDw (Group, DwNum, PadCfgLock);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will write GPIO Lock/LockTx register using SBI.
+
+  @param[in] RegType              GPIO register (Lock or LockTx)
+  @param[in] Group                GPIO group number
+  @param[in] DwNum                Register number for current group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in] LockRegAndMask       Mask which will be AND'ed with Lock register value
+  @param[in] LockRegOrMask        Mask which will be Or'ed with Lock register value
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_UNSUPPORTED         Feature is not supported for this group or pad
+**/
+STATIC
+EFI_STATUS
+GpioWriteLockReg (
+  IN GPIO_REG                  RegType,
+  IN GPIO_GROUP                Group,
+  IN UINT32                    DwNum,
+  IN UINT32                    LockRegAndMask,
+  IN UINT32                    LockRegOrMask
+  )
+{
+  UINT8                  Response;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+  UINT32                 RegOffset;
+  UINT32                 OldLockVal;
+  UINT32                 NewLockVal;
+  UINT32                 GroupIndex;
+  EFI_STATUS             Status;
+  PCH_SBI_OPCODE         Opcode;
+
+  OldLockVal = 0;
+  NewLockVal = 0;
+
+  RegOffset = NO_REGISTER_FOR_PROPERTY;
+  GroupIndex = GpioGetGroupIndexFromGroup (Group);
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  switch (RegType) {
+    case GpioPadConfigLockRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].PadCfgLockOffset;
+      GpioGetPadCfgLockForGroupDw (Group, DwNum, &OldLockVal);
+      break;
+    case GpioPadLockOutputRegister:
+      RegOffset = GpioGroupInfo[GroupIndex].PadCfgLockTxOffset;
+      GpioGetPadCfgLockTxForGroupDw (Group, DwNum, &OldLockVal);
+      break;
+    default:
+      break;
+  }
+
+  //
+  // Check if selected register exists
+  //
+  if (RegOffset == NO_REGISTER_FOR_PROPERTY) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // If there are more then 32 pads per group then certain
+  // group information would be split into more then one DWord register.
+  // PadConfigLock and OutputLock registers when used for group containing more than 32 pads
+  // are not placed in a continuous way, e.g:
+  // 0x0 - PadConfigLock_DW0
+  // 0x4 - OutputLock_DW0
+  // 0x8 - PadConfigLock_DW1
+  // 0xC - OutputLock_DW1
+  //
+  RegOffset += DwNum *0x8;
+
+  NewLockVal = (OldLockVal & LockRegAndMask) | LockRegOrMask;
+
+  if (IsGpioLockOpcodeSupported ()) {
+    Opcode = GpioLockUnlock;
+  } else {
+    Opcode = PrivateControlWrite;
+  }
+
+  Status = PchSbiExecutionEx (
+             GpioGroupInfo[GroupIndex].Community,
+             RegOffset,
+             Opcode,
+             FALSE,
+             0x000F,
+             0x0000,
+             0x0000,
+             &NewLockVal,
+             &Response
+             );
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
+
+/**
+  This internal procedure will calculate GPIO_RESET_CONFIG value  (new type)
+  based on provided PadRstCfg for a specific GPIO Pad.
+
+  @param[in]  GpioPad               GPIO Pad
+  @param[in]  PadRstCfg             GPIO PadRstCfg value
+
+  @retval GpioResetConfig           GPIO Reset configuration (new type)
+**/
+GPIO_RESET_CONFIG
+GpioResetConfigFromPadRstCfg (
+  IN  GPIO_PAD           GpioPad,
+  IN  UINT32             PadRstCfg
+  )
+{
+  GPIO_GROUP           Group;
+
+  static GPIO_RESET_CONFIG  PadRstCfgToGpioResetConfigMap[] = {
+                              GpioDswReset,
+                              GpioHostDeepReset,
+                              GpioPlatformReset,
+                              GpioResumeReset};
+
+  Group = GpioGetGroupFromGpioPad (GpioPad);
+
+  if (PadRstCfg < 4) {
+    if (!GpioIsDswGroup(Group) && PadRstCfg == 3) {
+      DEBUG ((DEBUG_ERROR, "ERROR: Pad %a is configured to be reset by Global Reset without being part of DSW group\n", GpioName (GpioPad)));
+    }
+    return PadRstCfgToGpioResetConfigMap[PadRstCfg];
+  }
+  return GpioResetDefault;
+}
+
+/**
+  This internal procedure will calculate PadRstCfg register value based
+  on provided GPIO Reset configuration for a certain pad.
+
+  @param[in]  GpioPad                   GPIO Pad
+  @param[in]  GpioResetConfig           GPIO Reset configuration
+  @param[out] PadRstCfg                 GPIO PadRstCfg value
+
+  @retval EFI_SUCCESS                   The function completed successfully
+  @retval EFI_INVALID_PARAMETER         Invalid configuration
+**/
+EFI_STATUS
+GpioPadRstCfgFromResetConfig (
+  IN  GPIO_PAD           GpioPad,
+  IN  GPIO_RESET_CONFIG  GpioResetConfig,
+  OUT UINT32             *PadRstCfg
+  )
+{
+  GPIO_GROUP           Group;
+
+  Group = GpioGetGroupFromGpioPad (GpioPad);
+
+  switch (GpioResetConfig) {
+    case GpioResetDefault:
+      *PadRstCfg = 0x0;
+      break;
+    case GpioHostDeepReset:
+      *PadRstCfg = V_GPIO_PCR_RST_CONF_DEEP_RST;
+      break;
+    case GpioPlatformReset:
+      *PadRstCfg = V_GPIO_PCR_RST_CONF_GPIO_RST;
+      break;
+    case GpioResumeReset:
+      if (GpioIsDswGroup (Group)) {
+        *PadRstCfg = V_GPIO_PCR_RST_CONF_RESUME_RST;
+      } else {
+        *PadRstCfg = V_GPIO_PCR_RST_CONF_POW_GOOD;
+      }
+      break;
+    case GpioDswReset:
+      if (GpioIsDswGroup (Group)) {
+        *PadRstCfg = V_GPIO_PCR_RST_CONF_POW_GOOD;
+      } else {
+        DEBUG ((DEBUG_ERROR, "GPIO ERROR: Only GPD group pads can use GpioDswReset: %a\n", GpioName (GpioPad)));
+        goto Error;
+      }
+      break;
+    default:
+      goto Error;
+  }
+
+  return EFI_SUCCESS;
+Error:
+  ASSERT (FALSE);
+  return EFI_INVALID_PARAMETER;
+}
+
+/**
+  This internal procedure will get GPIO_CONFIG data from PADCFG registers value
+
+  @param[in]  GpioPad                   GPIO Pad
+  @param[in]  PadCfgDwReg               PADCFG DWx register values
+  @param[out] GpioData                  GPIO Configuration data
+
+  @retval Status
+**/
+STATIC
+VOID
+GpioConfigFromPadCfgRegValue (
+  IN GPIO_PAD      GpioPad,
+  IN CONST UINT32  *PadCfgDwReg,
+  OUT GPIO_CONFIG  *GpioConfig
+  )
+{
+  UINT32               PadRstCfg;
+
+  //
+  // Get Reset Type (PadRstCfg)
+  //
+  PadRstCfg = (PadCfgDwReg[0] & B_GPIO_PCR_RST_CONF) >> N_GPIO_PCR_RST_CONF;
+
+  GpioConfig->PowerConfig = GpioResetConfigFromPadRstCfg (
+                              GpioPad,
+                              PadRstCfg
+                              );
+
+  //
+  // Get how interrupt is triggered (RxEvCfg)
+  //
+  GpioConfig->InterruptConfig = ((PadCfgDwReg[0] & B_GPIO_PCR_RX_LVL_EDG) >> (N_GPIO_PCR_RX_LVL_EDG - (N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS + 1))) | (0x1 << N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS);
+
+  //
+  // Get interrupt generation (GPIRoutIOxAPIC/SCI/SMI/NMI)
+  //
+  GpioConfig->InterruptConfig |= ((PadCfgDwReg[0] & (B_GPIO_PCR_RX_NMI_ROUTE | B_GPIO_PCR_RX_SCI_ROUTE | B_GPIO_PCR_RX_SMI_ROUTE | B_GPIO_PCR_RX_APIC_ROUTE)) >> (N_GPIO_PCR_RX_NMI_ROUTE - (N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS + 1))) | (0x1 << N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS);
+
+  //
+  // Get GPIO direction (GPIORxDis and GPIOTxDis)
+  //
+  GpioConfig->Direction = ((PadCfgDwReg[0] & (B_GPIO_PCR_RXDIS | B_GPIO_PCR_TXDIS)) >> (N_GPIO_PCR_TXDIS - (N_GPIO_DIRECTION_DIR_BIT_POS + 1))) | (0x1 << N_GPIO_DIRECTION_DIR_BIT_POS);
+
+  //
+  // Get GPIO input inversion (RXINV)
+  // (Only meaningful if input enabled)
+  //
+  if((PadCfgDwReg[0] & B_GPIO_PCR_RXDIS) == 0) {
+    GpioConfig->Direction |= ((PadCfgDwReg[0] & B_GPIO_PCR_RXINV) >> (N_GPIO_PCR_RXINV - (N_GPIO_DIRECTION_INV_BIT_POS + 1))) | (0x1 << N_GPIO_DIRECTION_INV_BIT_POS);
+  }
+
+  //
+  // Get GPIO output state (GPIOTxState)
+  //
+  GpioConfig->OutputState = ((PadCfgDwReg[0] & B_GPIO_PCR_TX_STATE) << (N_GPIO_PCR_TX_STATE + (N_GPIO_OUTPUT_BIT_POS + 1))) | (0x1 << N_GPIO_OUTPUT_BIT_POS);
+
+  //
+  // Configure GPIO RX raw override to '1' (RXRAW1)
+  //
+  GpioConfig->OtherSettings = ((PadCfgDwReg[0] & B_GPIO_PCR_RX_RAW1) >> (N_GPIO_PCR_RX_RAW1 - (N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS + 1))) | (0x1 << N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS);
+
+  //
+  // Get GPIO Pad Mode (PMode)
+  //
+  GpioConfig->PadMode = ((PadCfgDwReg[0] & B_GPIO_PCR_PAD_MODE) >> (N_GPIO_PCR_PAD_MODE - (N_GPIO_PAD_MODE_BIT_POS + 1))) | (0x1 << N_GPIO_PAD_MODE_BIT_POS);
+
+  //
+  // Get GPIO termination (Term)
+  //
+  GpioConfig->ElectricalConfig = ((PadCfgDwReg[1] & B_GPIO_PCR_TERM) >> (N_GPIO_PCR_TERM - (N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS + 1))) | (0x1 << N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS);
+}
+
+/**
+  This procedure will read multiple GPIO settings
+
+  @param[in]  GpioPad                   GPIO Pad
+  @param[out] GpioData                  GPIO data structure
+
+  @retval EFI_SUCCESS                   The function completed successfully
+  @retval EFI_INVALID_PARAMETER         Invalid group or pad number
+**/
+EFI_STATUS
+GpioGetPadConfig (
+  IN  GPIO_PAD               GpioPad,
+  OUT GPIO_CONFIG            *GpioData
+  )
+{
+  UINT32               PadCfgDwReg[GPIO_PADCFG_DW_REG_NUMBER];
+  UINT32               RegVal;
+  GPIO_GROUP           Group;
+  UINT32               PadNumber;
+  UINT32               PadBitPosition;
+
+  Group = GpioGetGroupFromGpioPad (GpioPad);
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+  PadBitPosition = GPIO_GET_PAD_POSITION (PadNumber);
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (!GpioIsPadHostOwned (GpioPad)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Read PADCFG DW0 register
+  //
+  PadCfgDwReg[0] = GpioReadPadCfgReg (GpioPad, 0);
+
+  //
+  // Read PADCFG DW1 register
+  //
+  PadCfgDwReg[1] = GpioReadPadCfgReg (GpioPad, 1);
+
+  //
+  // Read PADCFG DW2 register
+  //
+  PadCfgDwReg[2] = GpioReadPadCfgReg (GpioPad, 2);
+
+  GpioConfigFromPadCfgRegValue (
+    GpioPad,
+    PadCfgDwReg,
+    GpioData
+    );
+
+  //
+  // Read HOSTSW_OWN registers
+  //
+  GpioReadReg (
+    GpioHostOwnershipRegister,
+    Group,
+    GPIO_GET_DW_NUM (PadNumber),
+    &RegVal
+    );
+
+  //
+  // Get Host Software Ownership
+  //
+  GpioData->HostSoftPadOwn = (((RegVal >> PadBitPosition) & 0x1) << (N_GPIO_HOSTSW_OWN_BIT_POS + 1)) | (0x1 << N_GPIO_HOSTSW_OWN_BIT_POS);
+
+  //
+  // Read PADCFGLOCK register
+  //
+  GpioReadReg (
+    GpioPadConfigLockRegister,
+    Group,
+    GPIO_GET_DW_NUM (PadNumber),
+    &RegVal
+    );
+
+  //
+  // Get Pad Configuration Lock state
+  //
+  GpioData->LockConfig = ((!((RegVal >> PadBitPosition) & 0x1)) << 1) | BIT0;
+
+  //
+  // Read PADCFGLOCKTX register
+  //
+  GpioReadReg (
+    GpioPadLockOutputRegister,
+    Group,
+    GPIO_GET_DW_NUM (PadNumber),
+    &RegVal
+    );
+
+  //
+  // Get Pad Configuration Lock Tx state
+  //
+  GpioData->LockConfig |= ((!((RegVal >> PadBitPosition) & 0x1)) << 3) | BIT2;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will calculate PADCFG register value based on GpioConfig data
+
+  @param[in]  GpioPad                   GPIO Pad
+  @param[in]  GpioConfig                GPIO Configuration data
+  @param[out] PadCfgDwReg               PADCFG DWx register value
+  @param[out] PadCfgDwRegMask           Mask with PADCFG DWx register bits to be modified
+
+  @retval Status
+**/
+EFI_STATUS
+GpioPadCfgRegValueFromGpioConfig (
+  IN  GPIO_PAD           GpioPad,
+  IN  CONST GPIO_CONFIG  *GpioConfig,
+  OUT UINT32             *PadCfgDwReg,
+  OUT UINT32             *PadCfgDwRegMask
+  )
+{
+  UINT32               PadRstCfg;
+
+  //
+  // Configure Reset Type (PadRstCfg)
+  // Reset configuration depends on group type.
+  // This field requires support for new and deprecated settings.
+  //
+  GpioPadRstCfgFromResetConfig (
+    GpioPad,
+    GpioConfig->PowerConfig,
+    &PadRstCfg
+    );
+
+  PadCfgDwRegMask[0] |= ((((GpioConfig->PowerConfig & B_GPIO_RESET_CONFIG_RESET_MASK) >> N_GPIO_RESET_CONFIG_RESET_BIT_POS) == GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_RST_CONF);
+  PadCfgDwReg[0] |= PadRstCfg << N_GPIO_PCR_RST_CONF;
+
+  //
+  // Configure how interrupt is triggered (RxEvCfg)
+  //
+  PadCfgDwRegMask[0] |= ((((GpioConfig->InterruptConfig & B_GPIO_INT_CONFIG_INT_TYPE_MASK) >> N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS) == GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_RX_LVL_EDG);
+  PadCfgDwReg[0] |= (((GpioConfig->InterruptConfig & B_GPIO_INT_CONFIG_INT_TYPE_MASK) >> (N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS + 1)) << N_GPIO_PCR_RX_LVL_EDG);
+
+  //
+  // Configure interrupt generation (GPIRoutIOxAPIC/SCI/SMI/NMI)
+  //
+  PadCfgDwRegMask[0] |= ((((GpioConfig->InterruptConfig & B_GPIO_INT_CONFIG_INT_SOURCE_MASK) >> N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS) == GpioHardwareDefault)  ? 0x0 : (B_GPIO_PCR_RX_NMI_ROUTE | B_GPIO_PCR_RX_SCI_ROUTE | B_GPIO_PCR_RX_SMI_ROUTE | B_GPIO_PCR_RX_APIC_ROUTE));
+  PadCfgDwReg[0] |= (((GpioConfig->InterruptConfig & B_GPIO_INT_CONFIG_INT_SOURCE_MASK) >> (N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS + 1)) << N_GPIO_PCR_RX_NMI_ROUTE);
+
+  //
+  // Configure GPIO direction (GPIORxDis and GPIOTxDis)
+  //
+  PadCfgDwRegMask[0] |= ((((GpioConfig->Direction & B_GPIO_DIRECTION_DIR_MASK) >> N_GPIO_DIRECTION_DIR_BIT_POS) == GpioHardwareDefault) ? 0x0 : (B_GPIO_PCR_RXDIS | B_GPIO_PCR_TXDIS));
+  PadCfgDwReg[0] |= (((GpioConfig->Direction & B_GPIO_DIRECTION_DIR_MASK) >> (N_GPIO_DIRECTION_DIR_BIT_POS + 1)) << N_GPIO_PCR_TXDIS);
+
+  //
+  // Configure GPIO input inversion (RXINV)
+  //
+  PadCfgDwRegMask[0] |= ((((GpioConfig->Direction & B_GPIO_DIRECTION_INV_MASK) >> N_GPIO_DIRECTION_INV_BIT_POS) == GpioHardwareDefault) ?  0x0 : B_GPIO_PCR_RXINV);
+  PadCfgDwReg[0] |= (((GpioConfig->Direction & B_GPIO_DIRECTION_INV_MASK) >> (N_GPIO_DIRECTION_INV_BIT_POS + 1)) << N_GPIO_PCR_RXINV);
+
+  //
+  // Configure GPIO output state (GPIOTxState)
+  //
+  PadCfgDwRegMask[0] |= ((((GpioConfig->OutputState & B_GPIO_OUTPUT_MASK) >> N_GPIO_OUTPUT_BIT_POS) == GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_TX_STATE);
+  PadCfgDwReg[0] |= (((GpioConfig->OutputState & B_GPIO_OUTPUT_MASK) >> (N_GPIO_OUTPUT_BIT_POS + 1)) << N_GPIO_PCR_TX_STATE);
+
+  //
+  // Configure GPIO RX raw override to '1' (RXRAW1)
+  //
+  PadCfgDwRegMask[0] |= ((((GpioConfig->OtherSettings & B_GPIO_OTHER_CONFIG_RXRAW_MASK) >> N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS) == GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_RX_RAW1);
+  PadCfgDwReg[0] |= (((GpioConfig->OtherSettings & B_GPIO_OTHER_CONFIG_RXRAW_MASK) >> (N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS + 1)) << N_GPIO_PCR_RX_RAW1);
+
+  //
+  // Configure GPIO Pad Mode (PMode)
+  //
+  PadCfgDwRegMask[0] |= ((((GpioConfig->PadMode & B_GPIO_PAD_MODE_MASK) >> N_GPIO_PAD_MODE_BIT_POS) == GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_PAD_MODE);
+  PadCfgDwReg[0] |= (((GpioConfig->PadMode & B_GPIO_PAD_MODE_MASK) >> (N_GPIO_PAD_MODE_BIT_POS + 1)) << N_GPIO_PCR_PAD_MODE);
+
+  //
+  // Configure GPIO termination (Term)
+  //
+  PadCfgDwRegMask[1] |= ((((GpioConfig->ElectricalConfig & B_GPIO_ELECTRICAL_CONFIG_TERMINATION_MASK) >> N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS) == GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_TERM);
+  PadCfgDwReg[1] |= (((GpioConfig->ElectricalConfig & B_GPIO_ELECTRICAL_CONFIG_TERMINATION_MASK) >> (N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS + 1)) << N_GPIO_PCR_TERM);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will configure multiple GPIO settings
+
+  @param[in] GpioPad                    GPIO Pad
+  @param[in] GpioData                   GPIO data structure
+
+  @retval EFI_SUCCESS                   The function completed successfully
+  @retval EFI_INVALID_PARAMETER         Invalid group or pad number
+**/
+EFI_STATUS
+GpioSetPadConfig (
+  IN GPIO_PAD                  GpioPad,
+  IN GPIO_CONFIG               *GpioData
+  )
+{
+  EFI_STATUS           Status;
+  UINT32               PadCfgDwReg[GPIO_PADCFG_DW_REG_NUMBER];
+  UINT32               PadCfgDwRegMask[GPIO_PADCFG_DW_REG_NUMBER];
+  UINT32               HostSoftOwnReg;
+  UINT32               HostSoftOwnRegMask;
+  UINT32               GpiGpeEnReg;
+  UINT32               GpiGpeEnRegMask;
+  UINT32               GpiNmiEnReg;
+  UINT32               GpiNmiEnRegMask;
+  UINT32               GpiSmiEnReg;
+  UINT32               GpiSmiEnRegMask;
+  GPIO_GROUP           Group;
+  UINT32               GroupIndex;
+  UINT32               PadNumber;
+  UINT32               PadBitPosition;
+  UINT32               DwNum;
+  GPIO_LOCK_CONFIG     LockConfig;
+
+  ZeroMem (PadCfgDwReg, sizeof (PadCfgDwReg));
+  ZeroMem (PadCfgDwRegMask, sizeof (PadCfgDwRegMask));
+
+  Group = GpioGetGroupFromGpioPad (GpioPad);
+  GroupIndex = GpioGetGroupIndexFromGpioPad (GpioPad);
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+  PadBitPosition = GPIO_GET_PAD_POSITION (PadNumber);
+  DwNum = GPIO_GET_DW_NUM (PadNumber);
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (!GpioIsPadHostOwned (GpioPad)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Check if Pad enabled for SCI is to be in unlocked state
+  //
+  if (((GpioData->InterruptConfig & GpioIntSci) == GpioIntSci) &&
+      ((GpioData->LockConfig & B_GPIO_LOCK_CONFIG_PAD_CONF_LOCK_MASK) != GpioPadConfigUnlock)){
+    DEBUG ((DEBUG_ERROR, "GPIO ERROR: %a for SCI is not unlocked!\n", GpioName (GpioPad)));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Get GPIO PADCFG register value from GPIO config data
+  //
+  GpioPadCfgRegValueFromGpioConfig (
+    GpioPad,
+    GpioData,
+    PadCfgDwReg,
+    PadCfgDwRegMask
+    );
+
+  //
+  // Write PADCFG DW0 register
+  //
+  GpioWritePadCfgReg (
+    GpioPad,
+    0,
+    ~PadCfgDwRegMask[0],
+    PadCfgDwReg[0]
+    );
+
+  //
+  // Write PADCFG DW1 register
+  //
+  GpioWritePadCfgReg (
+    GpioPad,
+    1,
+    ~PadCfgDwRegMask[1],
+    PadCfgDwReg[1]
+    );
+
+  //
+  // Write PADCFG DW2 register
+  //
+  GpioWritePadCfgReg (
+    GpioPad,
+    2,
+    ~PadCfgDwRegMask[2],
+    PadCfgDwReg[2]
+    );
+
+  //
+  // Update value to be programmed in HOSTSW_OWN register
+  //
+  if ((GpioData->InterruptConfig & GpioIntSmi) == GpioIntSmi) {
+    HostSoftOwnRegMask = 1 << PadBitPosition;
+    HostSoftOwnReg = 1 << PadBitPosition;
+  } else {
+    HostSoftOwnRegMask = (GpioData->HostSoftPadOwn & 0x1) << PadBitPosition;
+    HostSoftOwnReg = (GpioData->HostSoftPadOwn >> 0x1) << PadBitPosition;
+  }
+
+  //
+  // Write HOSTSW_OWN registers
+  //
+  GpioWriteReg (
+    GpioHostOwnershipRegister,
+    Group,
+    DwNum,
+    ~HostSoftOwnRegMask,
+    HostSoftOwnReg
+    );
+
+  //
+  // Update value to be programmed in GPI_GPE_EN register
+  //
+  GpiGpeEnRegMask = (GpioData->InterruptConfig & 0x1) << PadBitPosition;
+  GpiGpeEnReg = ((GpioData->InterruptConfig & GpioIntSci) >> 3) << PadBitPosition;
+
+  //
+  // Write GPI_GPE_EN registers
+  //
+  GpioWriteReg (
+    GpioGpeEnableRegister,
+    Group,
+    DwNum,
+    ~GpiGpeEnRegMask,
+    GpiGpeEnReg
+    );
+
+  //
+  // Update value to be programmed in GPI_NMI_EN register
+  //
+  GpiNmiEnRegMask = (GpioData->InterruptConfig & 0x1) << PadBitPosition;
+  GpiNmiEnReg = ((GpioData->InterruptConfig & GpioIntNmi) >> 1) << PadBitPosition;
+
+  Status = GpioWriteReg (
+             GpioNmiEnableRegister,
+             Group,
+             DwNum,
+             ~GpiNmiEnRegMask,
+             GpiNmiEnReg
+             );
+  if (Status == EFI_UNSUPPORTED) {
+    if (GpiNmiEnReg == 0) {
+      //
+      // Not all GPIO have NMI capabilities. Since we always try to program this register,
+      // even when not enabling NMI for a pad so do not report such access as an error
+      //
+      Status = EFI_SUCCESS;
+    } else {
+      DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %a has no pads supporting NMI\n", GpioGetGroupName (GroupIndex)));
+      ASSERT (FALSE);
+      return Status;
+    }
+  }
+
+  //
+  // Update value to be programmed in GPI_SMI_EN register
+  //
+  GpiSmiEnRegMask = (GpioData->InterruptConfig & 0x1) << PadBitPosition;
+  GpiSmiEnReg = ((GpioData->InterruptConfig & GpioIntSmi) >> 2) << PadBitPosition;
+
+  Status = GpioWriteReg (
+             GpioSmiEnableRegister,
+             Group,
+             DwNum,
+             ~GpiSmiEnRegMask,
+             GpiSmiEnReg
+             );
+  if (Status == EFI_UNSUPPORTED) {
+    if (GpiSmiEnReg == 0) {
+      //
+      // Not all GPIO have SMI capabilities. Since we always try to program this register,
+      // even when not enabling SMI for a pad so do not report such access as an error
+      //
+      Status = EFI_SUCCESS;
+    } else {
+      DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %a has no pads supporting SMI\n", GpioGetGroupName (GroupIndex)));
+      ASSERT (FALSE);
+      return Status;
+    }
+  }
+
+  //
+  // Store unlock data
+  //
+  if (GpioData->LockConfig != GpioLockDefault) {
+    LockConfig = GpioData->LockConfig & B_GPIO_LOCK_CONFIG_PAD_CONF_LOCK_MASK;
+    //
+    // If pad in GpioMode is an output default action should be to leave output unlocked
+    //
+    if ((GpioData->PadMode == GpioPadModeGpio) &&
+      (GpioData->Direction == GpioDirOut) &&
+      ((GpioData->LockConfig & B_GPIO_LOCK_CONFIG_OUTPUT_LOCK_MASK) == GpioLockDefault)) {
+      LockConfig |= GpioOutputStateUnlock;
+    } else {
+      LockConfig |= GpioData->LockConfig & B_GPIO_LOCK_CONFIG_OUTPUT_LOCK_MASK;
+    }
+    Status = GpioStoreUnlockData (GpioPad, LockConfig);
+  }
+
+  return Status;
+}
+
+/**
+  This procedure will set GPIO output level
+
+  @param[in] GpioPad              GPIO pad
+  @param[in] Value                Output value
+                                  0: OutputLow, 1: OutputHigh
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioSetOutputValue (
+  IN GPIO_PAD                  GpioPad,
+  IN UINT32                    Value
+  )
+{
+  if (Value > 1) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!GpioIsPadHostOwned (GpioPad)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  GpioWritePadCfgReg (
+    GpioPad,
+    0,
+    (UINT32)~B_GPIO_PCR_TX_STATE,
+    Value << N_GPIO_PCR_TX_STATE
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will get GPIO output level
+
+  @param[in]  GpioPad             GPIO pad
+  @param[out] OutputVal           GPIO Output value
+                                  0: OutputLow, 1: OutputHigh
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetOutputValue (
+  IN GPIO_PAD                  GpioPad,
+  OUT UINT32                   *OutputVal
+  )
+{
+  UINT32      PadCfgReg;
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!GpioIsPadHostOwned (GpioPad)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  PadCfgReg = GpioReadPadCfgReg (GpioPad, 0);
+
+  *OutputVal = (PadCfgReg & B_GPIO_PCR_TX_STATE) >> N_GPIO_PCR_TX_STATE;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will get GPIO input level
+
+  @param[in] GpioPad              GPIO pad
+  @param[out] InputVal            GPIO Input value
+                                  0: InputLow, 1: InpuHigh
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetInputValue (
+  IN GPIO_PAD                  GpioPad,
+  OUT UINT32                   *InputVal
+  )
+{
+  UINT32      PadCfgReg;
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!GpioIsPadHostOwned (GpioPad)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  PadCfgReg = GpioReadPadCfgReg (GpioPad, 0);
+
+  *InputVal = (PadCfgReg & B_GPIO_PCR_RX_STATE) >> N_GPIO_PCR_RX_STATE;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will get GPIO IOxAPIC interrupt number
+
+  @param[in]  GpioPad             GPIO pad
+  @param[out] IrqNum              IRQ number
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetPadIoApicIrqNumber (
+  IN GPIO_PAD                  GpioPad,
+  OUT UINT32                   *IrqNum
+  )
+{
+  UINT32      PadCfgReg;
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!GpioIsPadHostOwned (GpioPad)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  PadCfgReg = GpioReadPadCfgReg (GpioPad, 1);
+
+  *IrqNum = (PadCfgReg & B_GPIO_PCR_INTSEL) >> N_GPIO_PCR_INTSEL;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will configure GPIO input inversion
+
+  @param[in] GpioPad              GPIO pad
+  @param[in] Value                Value for GPIO input inversion
+                                  0: No input inversion, 1: Invert input
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioSetInputInversion (
+  IN GPIO_PAD                  GpioPad,
+  IN UINT32                    Value
+  )
+{
+  if (Value > 1) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!GpioIsPadHostOwned (GpioPad)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  GpioWritePadCfgReg (
+    GpioPad,
+    0,
+    (UINT32)~B_GPIO_PCR_RXINV,
+    Value << N_GPIO_PCR_RXINV
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will get GPIO pad input inversion value
+
+  @param[in]  GpioPad             GPIO pad
+  @param[out] InvertState         GPIO inversion state
+                                  0: No input inversion, 1: Inverted input
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetInputInversion (
+  IN  GPIO_PAD                 GpioPad,
+  OUT UINT32                   *InvertState
+  )
+{
+  UINT32      PadCfgReg;
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!GpioIsPadHostOwned (GpioPad)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  PadCfgReg = GpioReadPadCfgReg (GpioPad, 0);
+
+  *InvertState = (PadCfgReg & B_GPIO_PCR_RXINV) >> N_GPIO_PCR_RXINV;
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will set GPIO interrupt settings
+
+  @param[in] GpioPad              GPIO pad
+  @param[in] Value                Value of Level/Edge
+                                  use GPIO_INT_CONFIG as argument
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioSetPadInterruptConfig (
+  IN GPIO_PAD                 GpioPad,
+  IN GPIO_INT_CONFIG          Value
+  )
+{
+  EFI_STATUS  Status;
+  UINT32      RxLvlEdgeValue;
+  UINT32      IntRouteValue;
+  UINT32      PadNumber;
+  UINT32      GpeEnable;
+  UINT32      NmiEnable;
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!GpioIsPadHostOwned (GpioPad)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = EFI_SUCCESS;
+
+  if (((Value & B_GPIO_INT_CONFIG_INT_TYPE_MASK) >> N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS) != GpioHardwareDefault) {
+    RxLvlEdgeValue = ((Value & B_GPIO_INT_CONFIG_INT_TYPE_MASK) >> (N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS + 1)) << N_GPIO_PCR_RX_LVL_EDG;
+
+    GpioWritePadCfgReg (
+      GpioPad,
+      0,
+      (UINT32)~B_GPIO_PCR_RX_LVL_EDG,
+      RxLvlEdgeValue
+      );
+  }
+
+  if (((Value & B_GPIO_INT_CONFIG_INT_SOURCE_MASK) >> N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS) != GpioHardwareDefault) {
+
+    IntRouteValue = ((Value & B_GPIO_INT_CONFIG_INT_SOURCE_MASK) >> (N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS + 1)) << N_GPIO_PCR_RX_NMI_ROUTE;
+
+    GpioWritePadCfgReg (
+      GpioPad,
+      0,
+      (UINT32)~(B_GPIO_PCR_RX_NMI_ROUTE | B_GPIO_PCR_RX_SCI_ROUTE | B_GPIO_PCR_RX_SMI_ROUTE | B_GPIO_PCR_RX_APIC_ROUTE),
+      IntRouteValue
+      );
+
+    if ((Value & GpioIntSci) == GpioIntSci) {
+      GpeEnable = 0x1;
+    } else {
+      GpeEnable = 0x0;
+    }
+
+    PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+
+    GpioWriteReg (
+      GpioGpeEnableRegister,
+      GpioGetGroupFromGpioPad (GpioPad),
+      GPIO_GET_DW_NUM (PadNumber),
+      ~(1 << GPIO_GET_PAD_POSITION (PadNumber)),
+      GpeEnable << GPIO_GET_PAD_POSITION (PadNumber)
+      );
+
+    if ((Value & GpioIntNmi) == GpioIntNmi) {
+      NmiEnable = 0x1;
+    } else {
+      NmiEnable = 0x0;
+    }
+
+    Status = GpioWriteReg (
+               GpioNmiEnableRegister,
+               GpioGetGroupFromGpioPad (GpioPad),
+               GPIO_GET_DW_NUM (PadNumber),
+               ~(1 << GPIO_GET_PAD_POSITION (PadNumber)),
+               NmiEnable << GPIO_GET_PAD_POSITION (PadNumber)
+               );
+    if (Status == EFI_UNSUPPORTED) {
+      if (NmiEnable == 0) {
+        //
+        // Not all GPIO have NMI capabilities. Since we always try to program this register,
+        // even when not enabling NMI for a pad so do not report such access as an error
+        //
+        return EFI_SUCCESS;
+      } else {
+        DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %a has no pads supporting NMI\n", GpioGetGroupName (GpioGetGroupIndexFromGpioPad (GpioPad))));
+      }
+    }
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  return Status;
+}
+
+/**
+  This procedure will set GPIO electrical settings
+
+  @param[in] GpioPad              GPIO pad
+  @param[in] Value                Value of termination
+                                  use GPIO_ELECTRICAL_CONFIG as argument
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioSetPadElectricalConfig (
+  IN GPIO_PAD                  GpioPad,
+  IN GPIO_ELECTRICAL_CONFIG    Value
+  )
+{
+  UINT32      TermValue;
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!GpioIsPadHostOwned (GpioPad)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (((Value & B_GPIO_ELECTRICAL_CONFIG_TERMINATION_MASK) >> N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS) != GpioHardwareDefault) {
+    TermValue = ((Value & B_GPIO_ELECTRICAL_CONFIG_TERMINATION_MASK) >> (N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS + 1)) << N_GPIO_PCR_TERM;
+
+    GpioWritePadCfgReg (
+      GpioPad,
+      1,
+      (UINT32)~B_GPIO_PCR_TERM,
+      TermValue
+      );
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will set GPIO Reset settings
+
+  @param[in] GpioPad              GPIO pad
+  @param[in] Value                Value for Pad Reset Configuration
+                                  use GPIO_RESET_CONFIG as argument
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioSetPadResetConfig (
+  IN GPIO_PAD                  GpioPad,
+  IN GPIO_RESET_CONFIG         Value
+  )
+{
+  UINT32      PadRstCfg;
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!GpioIsPadHostOwned (GpioPad)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (((Value & B_GPIO_RESET_CONFIG_RESET_MASK) >> N_GPIO_RESET_CONFIG_RESET_BIT_POS) != GpioHardwareDefault) {
+
+    //
+    // Reset configuration depends on group type.
+    // This field requires support for new and deprecated settings.
+    //
+    GpioPadRstCfgFromResetConfig (
+      GpioPad,
+      Value,
+      &PadRstCfg
+      );
+
+    GpioWritePadCfgReg (
+      GpioPad,
+      0,
+      (UINT32)~B_GPIO_PCR_RST_CONF,
+      PadRstCfg << N_GPIO_PCR_RST_CONF
+      );
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will get GPIO Reset settings
+
+  @param[in] GpioPad              GPIO pad
+  @param[in] Value                Value of Pad Reset Configuration
+                                  based on GPIO_RESET_CONFIG
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetPadResetConfig (
+  IN GPIO_PAD                  GpioPad,
+  IN GPIO_RESET_CONFIG         *Value
+  )
+{
+  UINT32      PadRstCfg;
+  UINT32      PadCfgDw0Reg;
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!GpioIsPadHostOwned (GpioPad)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  PadCfgDw0Reg = GpioReadPadCfgReg (GpioPad, 0);
+
+  //
+  // Get Reset Type (PadRstCfg)
+  //
+  PadRstCfg = (PadCfgDw0Reg & B_GPIO_PCR_RST_CONF) >> N_GPIO_PCR_RST_CONF;
+
+  *Value = GpioResetConfigFromPadRstCfg (
+             GpioPad,
+             PadRstCfg
+             );
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This procedure will get Gpio Pad Host Software Ownership
+
+  @param[in]  GpioPad             GPIO pad
+  @param[out] PadHostSwOwn        Value of Host Software Pad Owner
+                                  0: ACPI Mode, 1: GPIO Driver mode
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetHostSwOwnershipForPad (
+  IN GPIO_PAD                 GpioPad,
+  OUT UINT32                  *PadHostSwOwn
+  )
+{
+  UINT32      PadNumber;
+  UINT32      HostSwRegVal;
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+
+  GpioReadReg (
+    GpioHostOwnershipRegister,
+    GpioGetGroupFromGpioPad (GpioPad),
+    GPIO_GET_DW_NUM (PadNumber),
+    &HostSwRegVal
+    );
+
+  *PadHostSwOwn = (HostSwRegVal >> GPIO_GET_PAD_POSITION (PadNumber)) & 0x1;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will set Gpio Pad Host Software Ownership
+
+  @param[in] GpioPad              GPIO pad
+  @param[in] PadHostSwOwn         Pad Host Software Owner
+                                  0: ACPI Mode, 1: GPIO Driver mode
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioSetHostSwOwnershipForPad (
+  IN GPIO_PAD                  GpioPad,
+  IN UINT32                    PadHostSwOwn
+  )
+{
+  UINT32      PadNumber;
+
+  if (!GpioIsPadValid (GpioPad) || (PadHostSwOwn > 1)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+
+  return GpioWriteReg (
+           GpioHostOwnershipRegister,
+           GpioGetGroupFromGpioPad (GpioPad),
+           GPIO_GET_DW_NUM (PadNumber),
+           (UINT32)~(1 << GPIO_GET_PAD_POSITION (PadNumber)),
+           PadHostSwOwn << GPIO_GET_PAD_POSITION (PadNumber)
+           );
+}
+
+/**
+  This procedure will get Gpio Pad Ownership
+
+  @param[in] GpioPad              GPIO pad
+  @param[out] PadOwnVal           Value of Pad Ownership
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioGetPadOwnership (
+  IN  GPIO_PAD                GpioPad,
+  OUT GPIO_PAD_OWN            *PadOwnVal
+  )
+{
+  UINT32                 Mask;
+  UINT32                 RegOffset;
+  UINT32                 GroupIndex;
+  UINT32                 PadNumber;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+  UINT32                 PadOwnRegValue;
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  GroupIndex = GpioGetGroupIndexFromGpioPad (GpioPad);
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  //
+  // Calculate RegOffset using Pad Ownership offset and GPIO Pad number.
+  // One DWord register contains information for 8 pads.
+  //
+  RegOffset = GpioGroupInfo[GroupIndex].PadOwnOffset + (PadNumber >> 3) * 0x4;
+
+  //
+  // Calculate pad bit position within DWord register
+  //
+  PadNumber %= 8;
+  Mask = (BIT1 | BIT0) << (PadNumber * 4);
+
+  PadOwnRegValue = MmioRead32 (PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, RegOffset));
+
+  *PadOwnVal = (GPIO_PAD_OWN) ((PadOwnRegValue & Mask) >> (PadNumber * 4));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will check state of Pad Config Lock for pads within one group
+
+  @param[in]  Group               GPIO group
+  @param[in]  DwNum               PadCfgLock register number for current group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[out] PadCfgLockRegVal    Value of PadCfgLock register
+                                  Bit position - PadNumber
+                                  Bit value - 0: NotLocked, 1: Locked
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or DwNum parameter number
+**/
+EFI_STATUS
+GpioGetPadCfgLockForGroupDw (
+  IN  GPIO_GROUP                  Group,
+  IN  UINT32                      DwNum,
+  OUT UINT32                      *PadCfgLockRegVal
+  )
+{
+  if (!GpioIsGroupAndDwNumValid (Group, DwNum)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return GpioReadReg (
+           GpioPadConfigLockRegister,
+           Group,
+           DwNum,
+           PadCfgLockRegVal
+           );
+}
+
+/**
+  This procedure will check state of Pad Config Lock for selected pad
+
+  @param[in] GpioPad              GPIO pad
+  @param[out] PadCfgLock          PadCfgLock for selected pad
+                                  0: NotLocked, 1: Locked
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetPadCfgLock (
+  IN GPIO_PAD                   GpioPad,
+  OUT UINT32                    *PadCfgLock
+  )
+{
+  UINT32      PadNumber;
+  UINT32      PadCfgLockRegVal;
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+
+  GpioReadReg (
+    GpioPadConfigLockRegister,
+    GpioGetGroupFromGpioPad (GpioPad),
+    GPIO_GET_DW_NUM (PadNumber),
+    &PadCfgLockRegVal
+    );
+
+  *PadCfgLock = (PadCfgLockRegVal >> GPIO_GET_PAD_POSITION (PadNumber)) & 0x1;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will check state of Pad Config Tx Lock for pads within one group
+
+  @param[in]  Group               GPIO group
+  @param[in]  DwNum               PadCfgLockTx register number for current group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[out] PadCfgLockTxRegVal  Value of PadCfgLockTx register
+                                  Bit position - PadNumber
+                                  Bit value - 0: NotLockedTx, 1: LockedTx
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or DwNum parameter number
+**/
+EFI_STATUS
+GpioGetPadCfgLockTxForGroupDw (
+  IN  GPIO_GROUP                  Group,
+  IN  UINT32                      DwNum,
+  OUT UINT32                      *PadCfgLockTxRegVal
+  )
+{
+  if (!GpioIsGroupAndDwNumValid (Group, DwNum)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return GpioReadReg (
+           GpioPadLockOutputRegister,
+           Group,
+           DwNum,
+           PadCfgLockTxRegVal
+           );
+}
+
+/**
+  This procedure will check state of Pad Config Tx Lock for selected pad
+
+  @param[in] GpioPad              GPIO pad
+  @param[out] PadCfgLock          PadCfgLockTx for selected pad
+                                  0: NotLockedTx, 1: LockedTx
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetPadCfgLockTx (
+  IN GPIO_PAD                   GpioPad,
+  OUT UINT32                    *PadCfgLockTx
+  )
+{
+  UINT32      PadNumber;
+  UINT32      PadCfgLockTxRegVal;
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+
+  GpioReadReg (
+    GpioPadLockOutputRegister,
+    GpioGetGroupFromGpioPad (GpioPad),
+    GPIO_GET_DW_NUM (PadNumber),
+    &PadCfgLockTxRegVal
+    );
+
+  *PadCfgLockTx = (PadCfgLockTxRegVal >> GPIO_GET_PAD_POSITION (PadNumber)) & 0x1;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will clear PadCfgLock for selected pads within one group.
+  This function should be used only inside SMI.
+
+  @param[in]  Group               GPIO group
+  @param[in]  DwNum               PadCfgLock register number for current group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in]  PadsToUnlock        Bitmask for pads which are going to be unlocked,
+                                  Bit position - PadNumber
+                                  Bit value - 0: DoNotUnlock, 1: Unlock
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioUnlockPadCfgForGroupDw (
+  IN GPIO_GROUP                Group,
+  IN UINT32                    DwNum,
+  IN UINT32                    PadsToUnlock
+  )
+{
+  if (!GpioIsGroupAndDwNumValid (Group, DwNum)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return GpioWriteLockReg (
+           GpioPadConfigLockRegister,
+           Group,
+           DwNum,
+           ~PadsToUnlock,
+           0
+           );
+}
+
+/**
+  This procedure will clear PadCfgLock for selected pad.
+  This function should be used only inside SMI.
+
+  @param[in] GpioPad              GPIO pad
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioUnlockPadCfg (
+  IN GPIO_PAD                   GpioPad
+  )
+{
+  GPIO_GROUP   Group;
+  UINT32       PadNumber;
+
+  Group = GpioGetGroupFromGpioPad (GpioPad);
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+
+  return GpioUnlockPadCfgForGroupDw (
+           Group,
+           GPIO_GET_DW_NUM (PadNumber),
+           1 << GPIO_GET_PAD_POSITION (PadNumber)
+           );
+}
+
+/**
+  This procedure will set PadCfgLock for selected pads within one group
+
+  @param[in]  Group               GPIO group
+  @param[in]  DwNum               PadCfgLock register number for current group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in]  PadsToLock          Bitmask for pads which are going to be locked
+                                  Bit position - PadNumber
+                                  Bit value - 0: DoNotLock, 1: Lock
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or DwNum parameter number
+**/
+EFI_STATUS
+GpioLockPadCfgForGroupDw (
+  IN GPIO_GROUP                   Group,
+  IN UINT32                       DwNum,
+  IN UINT32                       PadsToLock
+  )
+{
+  if (!GpioIsGroupAndDwNumValid (Group, DwNum)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return GpioWriteLockReg (
+           GpioPadConfigLockRegister,
+           Group,
+           DwNum,
+           ~0u,
+           PadsToLock
+           );
+}
+
+/**
+  This procedure will set PadCfgLock for selected pad
+
+  @param[in] GpioPad              GPIO pad
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioLockPadCfg (
+  IN GPIO_PAD                   GpioPad
+  )
+{
+  GPIO_GROUP   Group;
+  UINT32       PadNumber;
+
+  Group = GpioGetGroupFromGpioPad (GpioPad);
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+
+  return GpioLockPadCfgForGroupDw (
+           Group,
+           GPIO_GET_DW_NUM (PadNumber),
+           1 << GPIO_GET_PAD_POSITION (PadNumber)
+           );
+}
+
+/**
+  This procedure will clear PadCfgLockTx for selected pads within one group.
+  This function should be used only inside SMI.
+
+  @param[in]  Group               GPIO group
+  @param[in]  DwNum               PadCfgLockTx register number for current group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in]  PadsToUnlockTx      Bitmask for pads which are going to be unlocked,
+                                  Bit position - PadNumber
+                                  Bit value - 0: DoNotUnLockTx, 1: LockTx
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioUnlockPadCfgTxForGroupDw (
+  IN GPIO_GROUP                Group,
+  IN UINT32                    DwNum,
+  IN UINT32                    PadsToUnlockTx
+  )
+{
+  if (!GpioIsGroupAndDwNumValid (Group, DwNum)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return GpioWriteLockReg (
+           GpioPadLockOutputRegister,
+           Group,
+           DwNum,
+           ~PadsToUnlockTx,
+           0
+           );
+}
+
+/**
+  This procedure will clear PadCfgLockTx for selected pad.
+  This function should be used only inside SMI.
+
+  @param[in] GpioPad              GPIO pad
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioUnlockPadCfgTx (
+  IN GPIO_PAD                   GpioPad
+  )
+{
+  GPIO_GROUP   Group;
+  UINT32       PadNumber;
+
+  Group = GpioGetGroupFromGpioPad (GpioPad);
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+
+  return GpioUnlockPadCfgTxForGroupDw (
+           Group,
+           GPIO_GET_DW_NUM (PadNumber),
+           1 << GPIO_GET_PAD_POSITION (PadNumber)
+           );
+}
+
+/**
+  This procedure will set PadCfgLockTx for selected pads within one group
+
+  @param[in]  Group               GPIO group
+  @param[in]  DwNum               PadCfgLock register number for current group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in]  PadsToLockTx        Bitmask for pads which are going to be locked,
+                                  Bit position - PadNumber
+                                  Bit value - 0: DoNotLockTx, 1: LockTx
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or DwNum parameter number
+**/
+EFI_STATUS
+GpioLockPadCfgTxForGroupDw (
+  IN GPIO_GROUP                   Group,
+  IN UINT32                       DwNum,
+  IN UINT32                       PadsToLockTx
+  )
+{
+  if (!GpioIsGroupAndDwNumValid (Group, DwNum)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return GpioWriteLockReg (
+           GpioPadLockOutputRegister,
+           Group,
+           DwNum,
+           ~0u,
+           PadsToLockTx
+           );
+}
+
+/**
+  This procedure will set PadCfgLockTx for selected pad
+
+  @param[in] GpioPad              GPIO pad
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioLockPadCfgTx (
+  IN GPIO_PAD                   GpioPad
+  )
+{
+  GPIO_GROUP   Group;
+  UINT32       PadNumber;
+
+  Group = GpioGetGroupFromGpioPad (GpioPad);
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+
+  return GpioLockPadCfgTxForGroupDw (
+           Group,
+           GPIO_GET_DW_NUM (PadNumber),
+           1 << GPIO_GET_PAD_POSITION (PadNumber)
+           );
+}
+
+/**
+  This procedure will get Group to GPE mapping.
+  It will assume that only first 32 pads can be mapped to GPE.
+  To handle cases where groups have more than 32 pads and higher part of group
+  can be mapped please refer to GpioGetGroupDwToGpeDwX()
+
+  @param[out] GroupToGpeDw0       GPIO group to be mapped to GPE_DW0
+  @param[out] GroupToGpeDw1       GPIO group to be mapped to GPE_DW1
+  @param[out] GroupToGpeDw2       GPIO group to be mapped to GPE_DW2
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioGetGroupToGpeDwX (
+  IN GPIO_GROUP               *GroupToGpeDw0,
+  IN GPIO_GROUP               *GroupToGpeDw1,
+  IN GPIO_GROUP               *GroupToGpeDw2
+  )
+{
+  UINT32     GroupDw[3];
+  UINT32     Index;
+  EFI_STATUS Status;
+
+  Status = GpioGetGroupDwToGpeDwX (
+             GroupToGpeDw0,
+             &GroupDw[0],
+             GroupToGpeDw1,
+             &GroupDw[1],
+             GroupToGpeDw2,
+             &GroupDw[2]
+             );
+
+  for (Index = 0; Index < ARRAY_SIZE (GroupDw); Index++) {
+    if (GroupDw[Index] != 0) {
+      Status = EFI_UNSUPPORTED;
+      ASSERT (FALSE);
+    }
+  }
+  return Status;
+}
+
+/**
+  This procedure will get Group to GPE mapping. If group has more than 32 bits
+  it is possible to map only single DW of pins (e.g. 0-31, 32-63) because
+  ACPI GPE_DWx register is 32 bits large.
+
+  @param[out]  GroupToGpeDw0       GPIO group mapped to GPE_DW0
+  @param[out]  GroupDwForGpeDw0    DW of pins mapped to GPE_DW0
+  @param[out]  GroupToGpeDw1       GPIO group mapped to GPE_DW1
+  @param[out]  GroupDwForGpeDw1    DW of pins mapped to GPE_DW1
+  @param[out]  GroupToGpeDw2       GPIO group mapped to GPE_DW2
+  @param[out]  GroupDwForGpeDw2    DW of pins mapped to GPE_DW2
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioGetGroupDwToGpeDwX (
+  OUT GPIO_GROUP                *GroupToGpeDw0,
+  OUT UINT32                    *GroupDwForGpeDw0,
+  OUT GPIO_GROUP                *GroupToGpeDw1,
+  OUT UINT32                    *GroupDwForGpeDw1,
+  OUT GPIO_GROUP                *GroupToGpeDw2,
+  OUT UINT32                    *GroupDwForGpeDw2
+  )
+{
+  UINT32                     PmcGpeDwXValue[3];
+  GPIO_GROUP                 GroupToGpeDwX[3];
+  UINT32                     GroupDwForGpeDwX[3];
+  UINT8                      GpeDwXIndex;
+  UINT32                     Index;
+  GPIO_GROUP_TO_GPE_MAPPING  *GpioGpeMap;
+  UINT32                     GpioGpeMapLength;
+
+  ZeroMem (GroupToGpeDwX, sizeof (GroupToGpeDwX));
+  ZeroMem (GroupDwForGpeDwX, sizeof (GroupDwForGpeDwX));
+
+  PmcGetGpioGpe (&PmcGpeDwXValue[0], &PmcGpeDwXValue[1], &PmcGpeDwXValue[2]);
+  GpioGetGroupToGpeMapping (&GpioGpeMap, &GpioGpeMapLength);
+  for (GpeDwXIndex = 0; GpeDwXIndex < 3; GpeDwXIndex++) {
+    for (Index = 0; Index < GpioGpeMapLength; Index++) {
+
+      if (GpioGpeMap[Index].PmcGpeDwxVal == PmcGpeDwXValue[GpeDwXIndex]) {
+        GroupToGpeDwX[GpeDwXIndex] = GpioGpeMap[Index].Group;
+        GroupDwForGpeDwX[GpeDwXIndex] = GpioGpeMap[Index].GroupDw;
+        break;
+      }
+    }
+  }
+
+  if ((GroupToGpeDwX[0] == 0) ||
+      (GroupToGpeDwX[1] == 0) ||
+      (GroupToGpeDwX[2] == 0)) {
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  *GroupToGpeDw0 = GroupToGpeDwX[0];
+  *GroupDwForGpeDw0 = GroupDwForGpeDwX[0];
+  *GroupToGpeDw1 = GroupToGpeDwX[1];
+  *GroupDwForGpeDw1 = GroupDwForGpeDwX[1];
+  *GroupToGpeDw2 = GroupToGpeDwX[2];
+  *GroupDwForGpeDw2 = GroupDwForGpeDwX[2];
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will get GPE number for provided GpioPad.
+  PCH allows to configure mapping between GPIO groups and related GPE (GpioSetGroupToGpeDwX())
+  what results in the fact that certain Pad can cause different General Purpose Event. Only three
+  GPIO groups can be mapped to cause unique GPE (1-tier), all others groups will be under one common
+  event (GPE_111 for 2-tier).
+
+  1-tier:
+  Returned GpeNumber is in range <0,95>. GpioGetGpeNumber() can be used
+  to determine what _LXX ACPI method would be called on event on selected GPIO pad
+
+  2-tier:
+  Returned GpeNumber is 0x6F (111). All GPIO pads which are not mapped to 1-tier GPE
+  will be under one master GPE_111 which is linked to _L6F ACPI method. If it is needed to determine
+  what Pad from 2-tier has caused the event, _L6F method should check GPI_GPE_STS and GPI_GPE_EN
+  registers for all GPIO groups not mapped to 1-tier GPE.
+
+  @param[in]  GpioPad             GPIO pad
+  @param[out] GpeNumber           GPE number
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetGpeNumber (
+  IN  GPIO_PAD                  GpioPad,
+  OUT UINT32                    *GpeNumber
+  )
+{
+  GPIO_GROUP           GroupToGpeDwX[3];
+  UINT32               GroupDw[3];
+  GPIO_GROUP           Group;
+  UINT32               PadNumber;
+  UINT32               Index;
+
+  Group = GpioGetGroupFromGpioPad (GpioPad);
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Get GPIO groups mapping to 1-tier GPE
+  // This mapping is dependent on GPIO IP implementation
+  // and may change between chipset generations
+  //
+  GpioGetGroupDwToGpeDwX (
+    &GroupToGpeDwX[0], &GroupDw[0],
+    &GroupToGpeDwX[1], &GroupDw[1],
+    &GroupToGpeDwX[2], &GroupDw[2]
+    );
+
+  //
+  // Check if pad is routed to 1-Tier GPE
+  //
+  for (Index = 0; Index < 3; Index++) {
+    if ((Group == GroupToGpeDwX[Index]) && (PadNumber >= (32 * GroupDw[Index])) && (PadNumber < (32 * (GroupDw[Index] + 1)))) {
+      *GpeNumber = PadNumber + (32 * Index) - (32 * GroupDw[Index]);
+      return EFI_SUCCESS;
+    }
+  }
+
+  //
+  // If Group number doesn't match any of above then
+  // it means that the pad is routed to 2-tier GPE
+  // which corresponds to  GPE_111 (0x6F)
+  //
+  *GpeNumber = PCH_GPIO_2_TIER_MASTER_GPE_NUMBER;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure is used to clear SMI STS for a specified Pad
+
+  @param[in]  GpioPad             GPIO pad
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioClearGpiSmiSts (
+  IN GPIO_PAD                   GpioPad
+  )
+{
+  GPIO_GROUP           Group;
+  UINT32               PadNumber;
+  UINT32               DwNum;
+  UINT32               PadBitPosition;
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Group = GpioGetGroupFromGpioPad (GpioPad);
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+  DwNum = GPIO_GET_DW_NUM (PadNumber);
+  PadBitPosition = GPIO_GET_PAD_POSITION (PadNumber);
+
+  //
+  // Clear GPI SMI Status bit by writing '1'
+  //
+  return GpioWriteReg (
+           GpioSmiStatusRegister,
+           Group,
+           DwNum,
+           0u,
+           (UINT32) (BIT0 << PadBitPosition)
+           );
+}
+
+/**
+  This procedure is used by PchSmiDispatcher and will clear
+  all GPI SMI Status bits
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioClearAllGpiSmiSts (
+  VOID
+  )
+{
+  UINT32         DwNum;
+  GPIO_GROUP     Group;
+  GPIO_GROUP     GroupMin;
+  GPIO_GROUP     GroupMax;
+
+  GroupMin = GpioGetLowestGroup ();
+  GroupMax = GpioGetHighestGroup ();
+
+  for (Group = GroupMin; Group <= GroupMax; Group++) {
+    //
+    // Clear all GPI SMI STS
+    //
+    for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGetPadPerGroup (Group)); DwNum++) {
+      GpioWriteReg (
+        GpioSmiStatusRegister,
+        Group,
+        DwNum,
+        0u,
+        0xFFFFFFFF
+        );
+    }
+  }
+  return EFI_SUCCESS;
+
+}
+
+/**
+  This procedure is used to disable all GPI SMI
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioDisableAllGpiSmi (
+  VOID
+  )
+{
+  UINT32         DwNum;
+  GPIO_GROUP     Group;
+  GPIO_GROUP     GroupMin;
+  GPIO_GROUP     GroupMax;
+  UINT32         SmiEnRegVal;
+
+  GroupMin = GpioGetLowestGroup ();
+  GroupMax = GpioGetHighestGroup ();
+
+  for (Group = GroupMin; Group <= GroupMax; Group++) {
+    //
+    // Disable all GPI SMI
+    //
+    for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGetPadPerGroup (Group)); DwNum++) {
+      //
+      // Check which pins have SMI_EN set
+      //
+      GpioReadReg (
+        GpioSmiEnableRegister,
+        Group,
+        DwNum,
+        &SmiEnRegVal
+        );
+      //
+      // Set HOSTSW_OWN to GPIO mode (1) for those pins to disable SMI capability
+      //
+      GpioWriteReg (
+        GpioHostOwnershipRegister,
+        Group,
+        DwNum,
+        ~0u,
+        SmiEnRegVal
+        );
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure is used to register GPI SMI dispatch function.
+
+  @param[in]  GpioPad             GPIO pad
+  @param[out] GpiNum              GPI number
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetGpiSmiNum (
+  IN GPIO_PAD          GpioPad,
+  OUT UINTN            *GpiNum
+  )
+{
+  UINT32                 GroupIndex;
+  UINT32                 Index;
+  UINT32                 PadNumber;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+
+  GroupIndex = GpioGetGroupIndexFromGpioPad (GpioPad);
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  *GpiNum = 0;
+
+  for (Index = 0; Index < GroupIndex; Index++) {
+    *GpiNum += (UINTN) (GpioGroupInfo[Index].PadPerGroup);
+  }
+  *GpiNum += (UINTN) PadNumber;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure is used to check GPIO inputs belongs to 2 tier or 1 tier architecture
+
+  @param[in]  GpioPad             GPIO pad
+
+  @retval     Data                0 means 1-tier, 1 means 2-tier
+**/
+BOOLEAN
+GpioCheckFor2Tier (
+  IN GPIO_PAD                  GpioPad
+  )
+{
+  UINT32               Data32;
+
+  GpioGetGpeNumber (GpioPad, &Data32);
+  if (Data32 == PCH_GPIO_2_TIER_MASTER_GPE_NUMBER) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+/**
+  This procedure is used to clear GPE STS for a specified GpioPad
+
+  @param[in]  GpioPad             GPIO pad
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioClearGpiGpeSts (
+  IN GPIO_PAD                  GpioPad
+  )
+{
+  GPIO_GROUP           Group;
+  UINT32               PadNumber;
+  UINT32               DwNum;
+  UINT32               PadBitPosition;
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Check for 2-tier
+  //
+  if (!(GpioCheckFor2Tier (GpioPad))) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Group = GpioGetGroupFromGpioPad (GpioPad);
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+  DwNum = GPIO_GET_DW_NUM (PadNumber);
+  PadBitPosition = GPIO_GET_PAD_POSITION (PadNumber);
+
+  //
+  // Clear GPI GPE Status bit by writing '1'
+  //
+  return GpioWriteReg (
+           GpioGpeStatusRegister,
+           Group,
+           DwNum,
+           0u,
+           (UINT32) (BIT0 << PadBitPosition)
+           );
+}
+
+/**
+  This procedure is used to read GPE STS for a specified Pad
+
+  @param[in]  GpioPad             GPIO pad
+  @param[out] GpeSts              Gpe status for given pad
+                                  The GpeSts is true if the status register is set for given Pad number
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetGpiGpeSts (
+  IN GPIO_PAD                  GpioPad,
+  OUT BOOLEAN                  *GpeSts
+  )
+{
+  UINT32               GpeStsRegVal;
+  GPIO_GROUP           Group;
+  UINT32               PadNumber;
+  UINT32               DwNum;
+  UINT32               PadBitPosition;
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Check for 2-tier
+  //
+  if (!(GpioCheckFor2Tier (GpioPad))) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Group = GpioGetGroupFromGpioPad (GpioPad);
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+  DwNum = GPIO_GET_DW_NUM (PadNumber);
+  PadBitPosition = GPIO_GET_PAD_POSITION (PadNumber);
+
+  //
+  // Read GPI GPE Status bits
+  //
+  GpioReadReg (
+    GpioGpeStatusRegister,
+    Group,
+    DwNum,
+    &GpeStsRegVal
+    );
+
+  *GpeSts = ((GpeStsRegVal >> PadBitPosition) & 0x1) != 0;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure is used to get SMI STS for a specified Pad
+
+  @param[in]  GpioPad             GPIO pad
+  @param[out] SmiSts              Smi status for given pad
+                                  The SmiSts is true if the status register is set for given Pad number
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetGpiSmiSts (
+  IN GPIO_PAD                   GpioPad,
+  OUT BOOLEAN                   *SmiSts
+  )
+{
+  GPIO_GROUP           Group;
+  UINT32               PadNumber;
+  UINT32               DwNum;
+  UINT32               PadBitPosition;
+  UINT32               SmiStsRegister;
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Group = GpioGetGroupFromGpioPad (GpioPad);
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+  DwNum = GPIO_GET_DW_NUM (PadNumber);
+  PadBitPosition = GPIO_GET_PAD_POSITION (PadNumber);
+
+  //
+  // Read the SMI Register
+  //
+  GpioReadReg (
+    GpioSmiStatusRegister,
+    Group,
+    DwNum,
+    &SmiStsRegister
+    );
+
+  *SmiSts = (SmiStsRegister & (BIT0 << PadBitPosition)) != 0;
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioLibrary.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioLibrary.h
new file mode 100644
index 0000000000..d197ee4898
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioLibrary.h
@@ -0,0 +1,82 @@
+/** @file
+  Header file for GPIO Lib implementation.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _GPIO_LIBRARY_H_
+#define _GPIO_LIBRARY_H_
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/GpioLib.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/GpioPrivateLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/SataLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PchSbiAccessLib.h>
+#include <Library/PmcPrivateLib.h>
+#include <Library/GpioHelpersLib.h>
+#include <Register/GpioRegs.h>
+
+//
+// Number of PADCFG_DW registers
+//
+#define GPIO_PADCFG_DW_REG_NUMBER  4
+
+/**
+  This internal procedure will calculate GPIO_RESET_CONFIG value  (new type)
+  based on provided PadRstCfg for a specific GPIO Pad.
+
+  @param[in]  GpioPad               GPIO Pad
+  @param[in]  PadRstCfg             GPIO PadRstCfg value
+
+  @retval GpioResetConfig           GPIO Reset configuration (new type)
+**/
+GPIO_RESET_CONFIG
+GpioResetConfigFromPadRstCfg (
+  IN  GPIO_PAD           GpioPad,
+  IN  UINT32             PadRstCfg
+  );
+
+/**
+  This internal procedure will calculate PadRstCfg register value based
+  on provided GPIO Reset configuration for a certain pad.
+
+  @param[in]  GpioPad                   GPIO Pad
+  @param[in]  GpioResetConfig           GPIO Reset configuration
+  @param[out] PadRstCfg                 GPIO PadRstCfg value
+
+  @retval EFI_SUCCESS                   The function completed successfully
+  @retval EFI_INVALID_PARAMETER         Invalid configuration
+**/
+EFI_STATUS
+GpioPadRstCfgFromResetConfig (
+  IN  GPIO_PAD           GpioPad,
+  IN  GPIO_RESET_CONFIG  GpioResetConfig,
+  OUT UINT32             *PadRstCfg
+  );
+
+/**
+  This procedure will calculate PADCFG register value based on GpioConfig data
+
+  @param[in]  GpioPad                   GPIO Pad
+  @param[in]  GpioConfig                GPIO Configuration data
+  @param[out] PadCfgDwReg               PADCFG DWx register value
+  @param[out] PadCfgDwRegMask           Mask with PADCFG DWx register bits to be modified
+
+  @retval Status
+**/
+EFI_STATUS
+GpioPadCfgRegValueFromGpioConfig (
+  IN  GPIO_PAD           GpioPad,
+  IN  CONST GPIO_CONFIG  *GpioConfig,
+  OUT UINT32             *PadCfgDwReg,
+  OUT UINT32             *PadCfgDwRegMask
+  );
+
+#endif // _GPIO_LIBRARY_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioNames.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioNames.c
new file mode 100644
index 0000000000..d21e77ba60
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioNames.c
@@ -0,0 +1,86 @@
+/** @file
+  This file contains GPIO name library implementation
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "GpioLibrary.h"
+#include <Library/PrintLib.h>
+
+/**
+  Generates GPIO group name from GpioPad
+
+  @param[in] GpioPad  GpioPad
+
+  @retval CHAR8*  Pointer to the GPIO group name
+**/
+CONST
+CHAR8*
+GpioGetGroupName (
+  IN UINT32  GroupIndex
+  )
+{
+  CONST GPIO_GROUP_NAME_INFO*  GroupNameInfo;
+
+  GroupNameInfo = GpioGetGroupNameInfo (GroupIndex);
+  if (GroupNameInfo == NULL) {
+    return NULL;
+  } else {
+    return GroupNameInfo->GpioGroupPrefix;
+  }
+}
+
+/**
+  Generates GPIO name from GpioPad
+
+  @param[in]  GpioPad             GpioPad
+  @param[out] GpioNameBuffer      Caller allocated buffer of GPIO_NAME_LENGTH_MAX size
+  @param[in]  GpioNameBufferSize  Size of the buffer
+
+  @retval CHAR8*  Pointer to the GPIO name
+**/
+CHAR8*
+GpioGetPadName (
+  IN GPIO_PAD  GpioPad,
+  OUT CHAR8*   GpioNameBuffer,
+  IN UINT32    GpioNameBufferSize
+  )
+{
+  UINT32                       GroupIndex;
+  UINT32                       PadNumber;
+  UINT32                       FirstUniquePadNumber;
+  CONST GPIO_GROUP_NAME_INFO*  GroupNameInfo;
+
+  if (GpioNameBuffer == NULL) {
+    ASSERT (FALSE);
+    return NULL;
+  }
+  if ((GpioNameBufferSize < GPIO_NAME_LENGTH_MAX) || !GpioIsPadValid (GpioPad)) {
+    ASSERT (FALSE);
+    *GpioNameBuffer = 0;
+    return NULL;
+  }
+
+  GroupIndex = GpioGetGroupIndexFromGpioPad (GpioPad);
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+  GroupNameInfo = GpioGetGroupNameInfo (GroupIndex);
+  if (GroupNameInfo == NULL) {
+    return NULL;
+  }
+
+  FirstUniquePadNumber = GpioGetPadNumberFromGpioPad (GroupNameInfo->FirstUniqueGpio);
+  if ((PadNumber < FirstUniquePadNumber) || (GroupNameInfo->GroupUniqueNames == NULL)) {
+    AsciiSPrint (GpioNameBuffer, GPIO_NAME_LENGTH_MAX, "GPIO_%a%d", GpioGetGroupName (GroupIndex), PadNumber);
+  } else {
+    if ((PadNumber - FirstUniquePadNumber) < GroupNameInfo->UniqueNamesTableSize) {
+      AsciiSPrint (GpioNameBuffer, GPIO_NAME_LENGTH_MAX, "GPIO_%a", GroupNameInfo->GroupUniqueNames[PadNumber - FirstUniquePadNumber]);
+    } else {
+      AsciiSPrint (GpioNameBuffer, GPIO_NAME_LENGTH_MAX, "GPIO_%08X", GpioPad);
+      ASSERT (FALSE);
+    }
+  }
+
+  return GpioNameBuffer;
+}
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioNativeLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioNativeLib.c
new file mode 100644
index 0000000000..97244c665b
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioNativeLib.c
@@ -0,0 +1,193 @@
+/** @file
+  This file contains routines for GPIO native and chipset specific usage
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "GpioLibrary.h"
+
+/**
+  This procedure will get number of pads for certain GPIO group
+
+  @param[in] Group            GPIO group number
+
+  @retval Value               Pad number for group
+                              If illegal group number then return 0
+**/
+UINT32
+GpioGetPadPerGroup (
+  IN GPIO_GROUP      Group
+  )
+{
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+  UINT32                 GroupIndex;
+  //
+  // Check if group argument exceeds GPIO GROUP INFO array
+  //
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+  GroupIndex = GpioGetGroupIndexFromGroup (Group);
+
+  if ((UINTN) GroupIndex >= GpioGroupInfoLength) {
+    return 0;
+  } else {
+    return GpioGroupInfo[GroupIndex].PadPerGroup;
+  }
+}
+
+/**
+  This procedure will get number of groups
+
+  @param[in] none
+
+  @retval Value               Group number
+**/
+UINT32
+GpioGetNumberOfGroups (
+  VOID
+  )
+{
+  UINT32                 GpioGroupInfoLength;
+
+  GpioGetGroupInfoTable (&GpioGroupInfoLength);
+  return GpioGroupInfoLength;
+}
+/**
+  This procedure will get lowest group
+
+  @param[in] none
+
+  @retval Value               Lowest Group
+**/
+GPIO_GROUP
+GpioGetLowestGroup (
+  VOID
+  )
+{
+  return GpioGetGroupFromGroupIndex (0);
+}
+/**
+  This procedure will get highest group
+
+  @param[in] none
+
+  @retval Value               Highest Group
+**/
+GPIO_GROUP
+GpioGetHighestGroup (
+  VOID
+  )
+{
+  return GpioGetGroupFromGroupIndex (GpioGetNumberOfGroups () - 1);
+}
+
+/**
+  This procedure will get group number
+
+  @param[in] GpioPad          Gpio Pad
+
+  @retval Value               Group number
+**/
+GPIO_GROUP
+GpioGetGroupFromGpioPad (
+  IN GPIO_PAD         GpioPad
+  )
+{
+  return GPIO_GET_GROUP_FROM_PAD (GpioPad);
+}
+
+/**
+  This procedure will get group index (0 based)
+
+  @param[in] GpioPad          Gpio Pad
+
+  @retval Value               Group Index
+**/
+UINT32
+GpioGetGroupIndexFromGpioPad (
+  IN GPIO_PAD        GpioPad
+  )
+{
+  return (UINT32) GPIO_GET_GROUP_INDEX_FROM_PAD (GpioPad);
+}
+
+/**
+  This procedure will get group index (0 based) from group
+
+  @param[in] GpioGroup        Gpio Group
+
+  @retval Value               Group Index
+**/
+UINT32
+GpioGetGroupIndexFromGroup (
+  IN GPIO_GROUP        GpioGroup
+  )
+{
+  return (UINT32) GPIO_GET_GROUP_INDEX (GpioGroup);
+}
+
+/**
+  This procedure will get group from group index (0 based)
+
+  @param[in] GroupIndex        Group Index
+
+  @retval GpioGroup            Gpio Group
+**/
+GPIO_GROUP
+GpioGetGroupFromGroupIndex (
+  IN UINT32        GroupIndex
+  )
+{
+  return GPIO_GROUP_DEF (GroupIndex, GpioGetThisChipsetId ());
+}
+
+/**
+  This procedure will get pad number (0 based) from Gpio Pad
+
+  @param[in] GpioPad          Gpio Pad
+
+  @retval Value               Pad Number
+**/
+UINT32
+GpioGetPadNumberFromGpioPad (
+  IN GPIO_PAD        GpioPad
+  )
+{
+  return (UINT32) GPIO_GET_PAD_NUMBER (GpioPad);
+}
+/**
+  This procedure will return GpioPad from Group and PadNumber
+
+  @param[in] Group              GPIO group
+  @param[in] PadNumber          GPIO PadNumber
+
+  @retval GpioPad               GpioPad
+**/
+GPIO_PAD
+GpioGetGpioPadFromGroupAndPadNumber (
+  IN GPIO_GROUP      Group,
+  IN UINT32          PadNumber
+  )
+{
+  return GPIO_PAD_DEF (Group,PadNumber);
+}
+
+/**
+  This procedure will return GpioPad from GroupIndex and PadNumber
+
+  @param[in] GroupIndex         GPIO GroupIndex
+  @param[in] PadNumber          GPIO PadNumber
+
+  @retval GpioPad               GpioPad
+**/
+GPIO_PAD
+GpioGetGpioPadFromGroupIndexAndPadNumber (
+  IN UINT32          GroupIndex,
+  IN UINT32          PadNumber
+  )
+{
+  GPIO_GROUP Group;
+
+  Group = GPIO_GROUP_DEF (GroupIndex, GpioGetThisChipsetId ());
+  return GPIO_PAD_DEF (Group, PadNumber);
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf
new file mode 100644
index 0000000000..0a888a38ba
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf
@@ -0,0 +1,49 @@
+## @file
+# Component description file for the PeiDxeSmmGpioLib
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmGpioLib
+FILE_GUID = 16EC5CA8-8195-4847-B6CB-662BD7B763F2
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = GpioLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PrintLib
+PchCycleDecodingLib
+PchSbiAccessLib
+PmcPrivateLib
+GpioPrivateLib
+SataLib
+GpioHelpersLib
+GpioCheckConflictLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+
+[Sources]
+GpioLib.c
+GpioNativeLib.c
+GpioInit.c
+GpioNames.c
+GpioLibrary.h
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c
new file mode 100644
index 0000000000..2c7a1987d9
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c
@@ -0,0 +1,119 @@
+/** @file
+  This file contains NULL implementation for GPIO Helpers Lib
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Uefi/UefiBaseType.h>
+#include <Library/GpioConfig.h>
+
+/**
+  This procedure stores GPIO pad unlock information
+
+  @param[in] GpioPad         GPIO pad
+  @param[in] GpioLockConfig  GPIO Lock Configuration
+
+  @retval Status
+**/
+EFI_STATUS
+GpioStoreUnlockData (
+  IN GPIO_PAD             GpioPad,
+  IN GPIO_LOCK_CONFIG     GpioLockConfig
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure stores GPIO group data about pads which PadConfig needs to be unlocked.
+
+  @param[in]  GroupIndex          GPIO group index
+  @param[in]  DwNum               DWORD index for a group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in]  UnlockedPads        DWORD bitmask for pads which are going to be left unlocked
+                                  Bit position - PadNumber
+                                  Bit value - 0: Skip, 1: Leave unlocked
+
+  @retval Status
+**/
+EFI_STATUS
+GpioStoreGroupDwUnlockPadConfigData (
+  IN UINT32                       GroupIndex,
+  IN UINT32                       DwNum,
+  IN UINT32                       UnlockedPads
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure stores GPIO group data about pads which Output state needs to be unlocked.
+
+  @param[in]  GroupIndex          GPIO group index
+  @param[in]  DwNum               DWORD index for a group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in]  UnlockedPads        DWORD bitmask for pads which are going to be left unlocked
+                                  Bit position - PadNumber
+                                  Bit value - 0: Skip, 1: Leave unlocked
+  @retval Status
+**/
+EFI_STATUS
+GpioStoreGroupDwUnlockOutputData (
+  IN UINT32                       GroupIndex,
+  IN UINT32                       DwNum,
+  IN UINT32                       UnlockedPads
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will get GPIO group data with pads, which PadConfig is supposed to be left unlock
+
+  @param[in]  GroupIndex          GPIO group index
+  @param[in]  DwNum               DWORD index for a group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @retval     UnlockedPads        DWORD bitmask for pads which are going to be left unlocked
+                                  Bit position - PadNumber
+                                  Bit value - 0: to be locked, 1: Leave unlocked
+**/
+UINT32
+GpioGetGroupDwUnlockPadConfigMask (
+  IN UINT32                       GroupIndex,
+  IN UINT32                       DwNum
+  )
+{
+  return 0;
+}
+
+/**
+  This procedure will get GPIO group data with pads, which Output is supposed to be left unlock
+
+  @param[in]  GroupIndex          GPIO group index
+  @param[in]  DwNum               DWORD index for a group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @retval     UnlockedPads        DWORD bitmask for pads which are going to be left unlocked
+                                  Bit position - PadNumber
+                                  Bit value - 0: to be locked, 1: Leave unlocked
+**/
+UINT32
+GpioGetGroupDwUnlockOutputMask (
+  IN UINT32                       GroupIndex,
+  IN UINT32                       DwNum
+  )
+{
+  return 0;
+}
+
+/**
+  Returns Gpio Override Level1 Information
+
+  @retval  TRUE/FALSE GPIO Override Level 1 Enabled/Disabled
+**/
+BOOLEAN
+GpioOverrideLevel1Enabled (
+  VOID
+  )
+{
+  return FALSE;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf
new file mode 100644
index 0000000000..756359d1e3
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf
@@ -0,0 +1,26 @@
+## @file
+# Component description file for the NULL GpioHelpersLib
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = BaseGpioHelpersLib
+FILE_GUID = AB282608-2A50-4AE3-9242-64064ECF40D4
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = GpioHelpersLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+BaseGpioHelpersLibNull.c
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioNameBufferLib/DxeGpioNameBufferLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioNameBufferLib/DxeGpioNameBufferLib.inf
new file mode 100644
index 0000000000..43860b7d20
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioNameBufferLib/DxeGpioNameBufferLib.inf
@@ -0,0 +1,32 @@
+## @file
+# Component description file for the DxeGpioMemLib
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeGpioNameBufferLib
+FILE_GUID = 16EC6AA8-81D5-4847-B6CB-662CDAB863F2
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_DRIVER
+LIBRARY_CLASS = GpioNameBufferLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[LibraryClasses]
+BaseLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Sources]
+GpioNameBufferDxe.c
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioNameBufferLib/GpioNameBufferDxe.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioNameBufferLib/GpioNameBufferDxe.c
new file mode 100644
index 0000000000..87dc9a2cd5
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioNameBufferLib/GpioNameBufferDxe.c
@@ -0,0 +1,19 @@
+/** @file
+  This file contains implementation of the GpioMemLib for DXE phase
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/GpioNameBufferLib.h>
+
+STATIC CHAR8 mGpioNameBuffer[GPIO_NAME_LENGTH_MAX];
+
+CHAR8*
+GpioGetStaticNameBuffer (
+  VOID
+  )
+{
+  return mGpioNameBuffer;
+}
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioPolicyLib/DxeGpioPolicyLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioPolicyLib/DxeGpioPolicyLib.c
new file mode 100644
index 0000000000..e9fe6f04e0
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioPolicyLib/DxeGpioPolicyLib.c
@@ -0,0 +1,87 @@
+/** @file
+  This file provides services for Gpio policy function
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/SiConfigBlockLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Protocol/PchPolicy.h>
+#include <ConfigBlock/Gpio/GpioDevConfig.h>
+
+/**
+  Print GPIO_DXE_CONFIG and serial out.
+
+  @param[in] PchPolicy            Pointer to a PCH_POLICY_PROTOCOL
+**/
+VOID
+GpioDxePrintConfig (
+  IN PCH_POLICY_PROTOCOL    *PchPolicy
+  )
+{
+  EFI_STATUS        Status;
+  GPIO_DXE_CONFIG   *GpioDxeConfig;
+
+  Status = GetConfigBlock ((VOID *) PchPolicy, &gGpioDxeConfigGuid, (VOID *) &GpioDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "------------------ GPIO DXE Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " HideGpioAcpiDevice : %d\n", GpioDxeConfig->HideGpioAcpiDevice));
+}
+
+/**
+  Load DXE Config block default for GPIO
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+GpioDxeLoadConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  GPIO_DXE_CONFIG  *GpioDxeConfig;
+  GpioDxeConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "GpioDxeConfig->Header.GuidHob.Name = %g\n", &GpioDxeConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "GpioDxeConfig->Header.GuidHob.Header.HobLength = 0x%x\n", GpioDxeConfig->Header.GuidHob.Header.HobLength));
+
+  GpioDxeConfig->HideGpioAcpiDevice = 0;
+}
+
+STATIC COMPONENT_BLOCK_ENTRY  mGpioBlocks = {
+  &gGpioDxeConfigGuid,
+  sizeof (GPIO_DXE_CONFIG),
+  GPIO_DXE_CONFIG_REVISION,
+  GpioDxeLoadConfigDefault
+};
+
+/**
+  Get Gpio config block table size.
+
+  @retval      Size of config block
+**/
+UINT16
+GpioDxeGetConfigBlockTotalSize (
+  VOID
+  )
+{
+  return mGpioBlocks.Size;
+}
+
+/**
+  Add Gpio ConfigBlock.
+
+  @param[in] ConfigBlockTableAddress    The pointer to config block table
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+GpioDxeAddConfigBlock (
+  IN VOID           *ConfigBlockTableAddress
+  )
+{
+  return AddComponentConfigBlocks (ConfigBlockTableAddress, &mGpioBlocks, 1);
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioPolicyLib/DxeGpioPolicyLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioPolicyLib/DxeGpioPolicyLib.inf
new file mode 100644
index 0000000000..1b9d53f40c
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioPolicyLib/DxeGpioPolicyLib.inf
@@ -0,0 +1,31 @@
+## @file
+# Component description file for the Gpio policy library
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeGpioPolicyLib
+FILE_GUID = 2D2B8ECA-E343-4036-A289-3F39545AEA06
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = DxeGpioPolicyLib
+
+[LibraryClasses]
+DebugLib
+ConfigBlockLib
+SiConfigBlockLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Sources]
+DxeGpioPolicyLib.c
+
+[Guids]
+gGpioDxeConfigGuid  ## CONSUMES
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioNamesVer2.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioNamesVer2.c
new file mode 100644
index 0000000000..4084583122
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioNamesVer2.c
@@ -0,0 +1,88 @@
+/** @file
+  This file contains GPIO name library implementation specific to Ver2
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Base.h>
+#include <Library/BaseLib.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/DebugLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/GpioPrivateLib.h>
+#include <Pins/GpioPinsVer2Lp.h>
+
+STATIC CONST CHAR8*  mGpioGppbNames[] = {
+  "GSPI0_CLK_LOOPBK",
+  "GSPI1_CLK_LOOPBK"
+};
+
+STATIC CONST CHAR8*  mGpioGppaNames[] = {
+  "SPI0_CLK_LOOPBK",
+  "ESPI_CLK_LOOPBK"
+};
+
+STATIC CONST CHAR8*  mPchLpGpioGpdNames[] = {
+  "INPUT3VSEL",
+  "SLP_LANB",
+  "SLP_SUSB",
+  "SLP_WAKEB",
+  "SLP_DRAM_RESETB"
+};
+
+STATIC CONST CHAR8*  mPchLpGpioGppdNames[] = {
+  "GSPI2_CLK_LOOPBK"
+};
+
+STATIC CONST CHAR8*  mGpioGppfNames[] = {
+  "GPPF_CLK_LOOPBK"
+};
+
+STATIC CONST CHAR8*  mGpioGppeNames[] = {
+  "GPPE_CLK_LOOPBK"
+};
+
+
+STATIC CONST GPIO_GROUP_NAME_INFO  mPchLpGroupDescriptors[] = {
+  GPIO_GROUP_NAME("GPP_B", GPIO_VER2_LP_GSPI0_CLK_LOOPBK, mGpioGppbNames),
+  GPIO_GROUP_NAME_BASIC(""),
+  GPIO_GROUP_NAME("GPP_A", GPIO_VER2_LP_ESPI_CLK_LOOPBK, mGpioGppaNames),
+  GPIO_GROUP_NAME_BASIC("GPP_R"),
+  GPIO_GROUP_NAME_BASIC(""),
+  GPIO_GROUP_NAME("GPD", GPIO_VER2_LP_INPUT3VSEL, mPchLpGpioGpdNames),
+  GPIO_GROUP_NAME_BASIC("GPP_S"),
+  GPIO_GROUP_NAME_BASIC("GPP_H"),
+  GPIO_GROUP_NAME("GPP_D", GPIO_VER2_LP_GSPI2_CLK_LOOPBK, mPchLpGpioGppdNames),
+  GPIO_GROUP_NAME_BASIC(""),
+  GPIO_GROUP_NAME_BASIC(""),
+  GPIO_GROUP_NAME_BASIC("GPP_C"),
+  GPIO_GROUP_NAME("GPP_F", GPIO_VER2_LP_GPPF_CLK_LOOPBK, mGpioGppfNames),
+  GPIO_GROUP_NAME_BASIC(""),
+  GPIO_GROUP_NAME("GPP_E", GPIO_VER2_LP_GPPE_CLK_LOOPBK, mGpioGppeNames),
+  GPIO_GROUP_NAME_BASIC(""),
+  GPIO_GROUP_NAME_BASIC(""),
+  GPIO_GROUP_NAME_BASIC("")
+};
+
+/**
+  Returns GPIO_GROUP_NAME_INFO corresponding to the given GpioPad
+
+  @param[in] GroupIndex  Group index
+
+  @retval GPIO_GROUP_NAME_INFO*  Pointer to the GPIO_GROUP_NAME_INFO
+  @reval  NULL                   If no group descriptor was found
+**/
+CONST
+GPIO_GROUP_NAME_INFO*
+GpioGetGroupNameInfo (
+  IN UINT32  GroupIndex
+  )
+{
+  if (GroupIndex < ARRAY_SIZE (mPchLpGroupDescriptors)) {
+    return &mPchLpGroupDescriptors[GroupIndex];
+  }
+
+  ASSERT (FALSE);
+  return NULL;
+}
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c
new file mode 100644
index 0000000000..f750d77e9a
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c
@@ -0,0 +1,395 @@
+/** @file
+  This file contains GPIO routines for RC usage
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/GpioLib.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/GpioPrivateLib.h>
+#include <Library/GpioNameBufferLib.h>
+#include <Register/PchPcrRegs.h>
+#include <Register/GpioRegs.h>
+
+/**
+  This procedure is used to check if GpioPad is valid for certain chipset
+
+  @param[in]  GpioPad             GPIO pad
+
+  @retval TRUE                    This pin is valid on this chipset
+          FALSE                   Incorrect pin
+**/
+BOOLEAN
+GpioIsCorrectPadForThisChipset (
+  IN  GPIO_PAD        GpioPad
+  )
+{
+  return ((GPIO_GET_CHIPSET_ID (GpioPad) == GpioGetThisChipsetId ()) &&
+         (GpioGetGroupIndexFromGpioPad (GpioPad) < GpioGetNumberOfGroups ()));
+}
+
+/**
+  This procedure is used by PchSmiDispatcher and will return information
+  needed to register GPI SMI.
+
+  @param[in]  Index                   GPI SMI number
+  @param[out] GpioPin                 GPIO pin
+  @param[out] GpiSmiBitOffset         GPI SMI bit position within GpiSmi Registers
+  @param[out] GpiHostSwOwnRegAddress  Address of HOSTSW_OWN register
+  @param[out] GpiSmiStsRegAddress     Address of GPI SMI status register
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioGetPadAndSmiRegs (
+  IN UINT32            Index,
+  OUT GPIO_PAD         *GpioPin,
+  OUT UINT8            *GpiSmiBitOffset,
+  OUT UINT32           *GpiHostSwOwnRegAddress,
+  OUT UINT32           *GpiSmiStsRegAddress
+  )
+{
+  UINT32                 GroupIndex;
+  UINT32                 PadNumber;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  GPIO_GROUP             GpioGroup;
+  UINT32                 GpioGroupInfoLength;
+  UINT32                 SmiStsRegOffset;
+  UINT32                 HostSwOwnRegOffset;
+  GPIO_PAD_OWN           PadOwnVal;
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  PadNumber = 0;
+  GroupIndex = 0;
+  for (GroupIndex = 0; GroupIndex < GpioGroupInfoLength; GroupIndex++) {
+    PadNumber = Index;
+    if (PadNumber < GpioGroupInfo[GroupIndex].PadPerGroup) {
+      //
+      // Found group and pad number
+      //
+      break;
+    }
+    Index = Index - GpioGroupInfo[GroupIndex].PadPerGroup;
+  }
+
+  //
+  // Check if legal pad number
+  //
+  if (PadNumber >= GpioGroupInfo[GroupIndex].PadPerGroup){
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Check if selected group has GPI SMI Enable and Status registers
+  //
+  if (GpioGroupInfo[GroupIndex].SmiEnOffset == NO_REGISTER_FOR_PROPERTY) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  GpioGroup = GpioGetGroupFromGroupIndex (GroupIndex);
+  *GpioPin = GpioGetGpioPadFromGroupAndPadNumber (GpioGroup, PadNumber);
+
+  DEBUG_CODE_BEGIN ();
+  //
+  // Check if selected GPIO Pad is not owned by CSME/ISH/IE
+  //
+  GpioGetPadOwnership (*GpioPin, &PadOwnVal);
+  if (PadOwnVal != GpioPadOwnHost) {
+    DEBUG ((DEBUG_ERROR, "GPIO ERROR: %a not owned by host!\n", GpioName (*GpioPin)));
+    return EFI_INVALID_PARAMETER;
+  }
+  DEBUG_CODE_END ();
+
+  *GpiSmiBitOffset = (UINT8)(PadNumber % 32);
+
+  HostSwOwnRegOffset = GpioGroupInfo[GroupIndex].HostOwnOffset + (PadNumber / 32) * 0x4;
+  *GpiHostSwOwnRegAddress = PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, HostSwOwnRegOffset);
+
+  SmiStsRegOffset = GpioGroupInfo[GroupIndex].SmiStsOffset + (PadNumber / 32) * 0x4;
+  *GpiSmiStsRegAddress = PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, SmiStsRegOffset);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will check if GpioPad is owned by host.
+
+  @param[in] GpioPad       GPIO pad
+
+  @retval TRUE             GPIO pad is owned by host
+  @retval FALSE            GPIO pad is not owned by host and should not be used with GPIO lib API
+**/
+BOOLEAN
+GpioIsPadHostOwned (
+  IN GPIO_PAD             GpioPad
+  )
+{
+  GPIO_PAD_OWN         PadOwnVal;
+
+  //
+  // Check if selected GPIO Pad is not owned by CSME/ISH
+  // If GPIO is not owned by Host all access to PadCfg will be dropped
+  //
+  GpioGetPadOwnership (GpioPad, &PadOwnVal);
+  if (PadOwnVal != GpioPadOwnHost) {
+    DEBUG ((DEBUG_ERROR, "GPIO ERROR: %a is not owned by host!\n", GpioName (GpioPad)));
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+/**
+  This procedure will check if GpioPad argument is valid.
+  Function will check below conditions:
+   - GpioPad represents a pad for current PCH
+   - GpioPad belongs to valid GpioGroup
+   - GPIO PadNumber is not greater than number of pads for this group
+
+  @param[in] GpioPad       GPIO pad
+
+  @retval TRUE             GPIO pad is valid and can be used with GPIO lib API
+  @retval FALSE            GPIO pad is invalid and cannot be used with GPIO lib API
+**/
+BOOLEAN
+GpioIsPadValid (
+  IN GPIO_PAD             GpioPad
+  )
+{
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+  UINT32                 PadNumber;
+  UINT32                 GroupIndex;
+
+  if (!GpioIsCorrectPadForThisChipset (GpioPad)) {
+    DEBUG ((DEBUG_ERROR, "GPIO ERROR: Incorrect GpioPad (0x%08x) used on this chipset!\n", GpioPad));
+    goto Error;
+  }
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  //
+  // Check if legal pin number
+  //
+  GroupIndex = GpioGetGroupIndexFromGpioPad (GpioPad);
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+  if (PadNumber >= GpioGroupInfo[GroupIndex].PadPerGroup) {
+    DEBUG ((DEBUG_ERROR, "GPIO ERROR: Pin number (%d) exceeds range of %a group (max: %d)\n",
+                                                                                   PadNumber,
+                                                                                   GpioGetGroupName (GroupIndex),
+                                                                                   GpioGroupInfo[GroupIndex].PadPerGroup));
+    goto Error;
+  }
+
+  return TRUE;
+Error:
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  This procedure will read GPIO Pad Configuration register
+
+  @param[in] GpioPad          GPIO pad
+  @param[in] DwReg            Choose PADCFG register: 0:DW0, 1:DW1
+
+  @retval PadCfgRegValue      PADCFG_DWx value
+**/
+UINT32
+GpioReadPadCfgReg (
+  IN GPIO_PAD             GpioPad,
+  IN UINT8                DwReg
+  )
+{
+  UINT32                 PadCfgReg;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+  UINT32                 GroupIndex;
+  UINT32                 PadNumber;
+
+  GroupIndex = GpioGetGroupIndexFromGpioPad (GpioPad);
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  //
+  // Create Pad Configuration register offset
+  //
+  PadCfgReg = GpioGroupInfo[GroupIndex].PadCfgOffset + S_GPIO_PCR_PADCFG * PadNumber + 0x4 * DwReg;
+
+  return MmioRead32 (PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, PadCfgReg));
+}
+
+/**
+  This procedure will write or read GPIO Pad Configuration register
+
+  @param[in] GpioPad              GPIO pad
+  @param[in] DwReg                Choose PADCFG register: 0:DW0, 1:DW1
+  @param[in] PadCfgAndMask        Mask to be AND'ed with PADCFG reg value
+  @param[in] PadCfgOrMask         Mask to be OR'ed with PADCFG reg value
+
+  @retval none
+**/
+VOID
+GpioWritePadCfgReg (
+  IN GPIO_PAD             GpioPad,
+  IN UINT8                DwReg,
+  IN UINT32               PadCfgAndMask,
+  IN UINT32               PadCfgOrMask
+  )
+{
+  UINT32                 PadCfgReg;
+  CONST GPIO_GROUP_INFO  *GpioGroupInfo;
+  UINT32                 GpioGroupInfoLength;
+  UINT32                 GroupIndex;
+  UINT32                 PadNumber;
+  UINT32                 PadCfgLock;
+  UINT32                 PadCfgLockTx;
+
+  PadCfgLock = 0;
+  PadCfgLockTx = 0;
+
+  //
+  // Check if Pad Configuration (except output state) is to be changed.
+  // If AND and OR masks will indicate that configuration fields (other than output control)
+  // are to be modified it means that there is a need to perform an unlock (if set)
+  //
+  if ((~PadCfgAndMask | PadCfgOrMask) & (UINT32)~B_GPIO_PCR_TX_STATE) {
+    GpioGetPadCfgLock (GpioPad, &PadCfgLock);
+    if (PadCfgLock) {
+      GpioUnlockPadCfg (GpioPad);
+    }
+  }
+
+  //
+  // Check if Pad Output state is to be changed
+  // If AND and OR masks will indicate that output control
+  // is to be modified it means that there is a need to perform an unlock (if set)
+  //
+  if ((~PadCfgAndMask | PadCfgOrMask) & B_GPIO_PCR_TX_STATE) {
+    GpioGetPadCfgLockTx (GpioPad, &PadCfgLockTx);
+    if (PadCfgLockTx) {
+      GpioUnlockPadCfgTx (GpioPad);
+    }
+  }
+
+  GroupIndex = GpioGetGroupIndexFromGpioPad (GpioPad);
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+
+  GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength);
+
+  //
+  // Create Pad Configuration register offset
+  //
+  PadCfgReg = GpioGroupInfo[GroupIndex].PadCfgOffset + S_GPIO_PCR_PADCFG * PadNumber + 0x4 * DwReg;
+
+  MmioAndThenOr32 (
+    PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, PadCfgReg),
+    PadCfgAndMask,
+    PadCfgOrMask
+    );
+
+  if (PadCfgLock) {
+    GpioLockPadCfg (GpioPad);
+  }
+  if (PadCfgLockTx) {
+    GpioLockPadCfgTx (GpioPad);
+  }
+}
+
+/**
+  This procedure will set GPIO mode
+
+  @param[in]  GpioPad             GPIO pad
+  @param[in]  PadModeValue        GPIO pad mode value
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid group or pad number
+**/
+EFI_STATUS
+GpioSetPadMode (
+  IN GPIO_PAD                GpioPad,
+  IN GPIO_PAD_MODE           PadModeValue
+  )
+{
+  UINT32               PadCfgOrMask;
+
+  PadCfgOrMask = 0;
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!GpioIsPadHostOwned (GpioPad)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (PadModeValue != (GPIO_PAD_MODE)GpioHardwareDefault) {
+
+    PadCfgOrMask = (((PadModeValue & B_GPIO_PAD_MODE_MASK) >> (N_GPIO_PAD_MODE_BIT_POS + 1)) << N_GPIO_PCR_PAD_MODE);
+
+    GpioWritePadCfgReg (
+      GpioPad,
+      0,
+      (UINT32)~B_GPIO_PCR_PAD_MODE,
+      PadCfgOrMask
+      );
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will get GPIO mode
+
+  @param[in]  GpioPad             GPIO pad
+  @param[out] PadModeValue        GPIO pad mode value
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_INVALID_PARAMETER   Invalid GpioPad
+**/
+EFI_STATUS
+GpioGetPadMode (
+  IN  GPIO_PAD                 GpioPad,
+  OUT GPIO_PAD_MODE            *PadModeValue
+  )
+{
+  UINT32        PadCfgRegValue;
+
+  if (!GpioIsPadValid (GpioPad)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!GpioIsPadHostOwned (GpioPad)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  PadCfgRegValue = GpioReadPadCfgReg (GpioPad, 0);
+
+  *PadModeValue = (GPIO_PAD_MODE)(((PadCfgRegValue & B_GPIO_PCR_PAD_MODE) >> (N_GPIO_PCR_PAD_MODE - (N_GPIO_PAD_MODE_BIT_POS + 1))) | (0x1 << N_GPIO_PAD_MODE_BIT_POS));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Generates GPIO name from GpioPad
+  This function returns pointer to the static buffer
+
+  @param[in] GpioPad  GpioPad
+
+  @retval CHAR8*  Pointer to the gpio name string
+**/
+CHAR8*
+GpioName (
+  IN GPIO_PAD  GpioPad
+  )
+{
+  return GpioGetPadName (GpioPad, GpioGetStaticNameBuffer (), GPIO_NAME_LENGTH_MAX);
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLibVer2.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLibVer2.c
new file mode 100644
index 0000000000..9fea5daa28
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLibVer2.c
@@ -0,0 +1,131 @@
+/** @file
+  This file contains VER2 specific GPIO information
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Uefi/UefiBaseType.h>
+#include <Library/DebugLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/GpioLib.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/GpioPrivateLib.h>
+#include <Library/GpioHelpersLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/CpuRegbarAccessLib.h>
+#include <Register/GpioRegsVer2.h>
+#include <Register/PmcRegsVer2.h>
+#include <Register/PchPcrRegs.h>
+#include <Pins/GpioPinsVer2Lp.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_GROUP_INFO mPchLpGpioGroupInfo[] = {
+  {PID_GPIOCOM0, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_PAD_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_HOSTSW_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_GPI_IS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_GPI_GPE_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_SMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_SMI_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_NMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_NMI_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_PADCFGLOCK,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_PADCFGLOCKTX,   R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_PADCFG_OFFSET,  GPIO_VER2_PCH_LP_GPIO_GPP_B_PAD_MAX}, //TGL PCH-LP GPP_B
+  {PID_GPIOCOM0, NO_REGISTER_FOR_PROPERTY,                   NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                     NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                         NO_REGISTER_FOR_PROPERTY,                         0},
+  {PID_GPIOCOM0, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_PAD_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_HOSTSW_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_GPI_IS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_PADCFGLOCK,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_PADCFGLOCKTX,   R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_PADCFG_OFFSET,  GPIO_VER2_PCH_LP_GPIO_GPP_A_PAD_MAX}, //TGL PCH-LP GPP_A
+  {PID_GPIOCOM5, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_PAD_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_HOSTSW_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_GPI_IS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_PADCFGLOCK,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_PADCFGLOCKTX,   R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_PADCFG_OFFSET,  GPIO_VER2_PCH_LP_GPIO_GPP_R_PAD_MAX}, //TGL PCH-LP GPP_R
+  {PID_GPIOCOM5, NO_REGISTER_FOR_PROPERTY,                   NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                     NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                         NO_REGISTER_FOR_PROPERTY,                         0},
+  {PID_GPIOCOM2, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_PAD_OWN,    R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_HOSTSW_OWN,    R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_GPI_IS,   R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_GPI_IE,   R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_GPI_GPE_STS,   R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_GPI_GPE_EN,   NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_PADCFGLOCK,    R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_PADCFGLOCKTX,     R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_PADCFG_OFFSET,    GPIO_VER2_PCH_LP_GPIO_GPD_PAD_MAX},   //TGL PCH-LP GPD
+  {PID_GPIOCOM1, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_PAD_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_HOSTSW_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_GPI_IS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_PADCFGLOCK,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_PADCFGLOCKTX,   R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_PADCFG_OFFSET,  GPIO_VER2_PCH_LP_GPIO_GPP_S_PAD_MAX}, //TGL PCH-LP GPP_S
+  {PID_GPIOCOM1, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_PAD_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_HOSTSW_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_GPI_IS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_PADCFGLOCK,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_PADCFGLOCKTX,   R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_PADCFG_OFFSET,  GPIO_VER2_PCH_LP_GPIO_GPP_H_PAD_MAX}, //TGL PCH-LP GPP_H
+  {PID_GPIOCOM1, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_PAD_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_HOSTSW_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_GPI_IS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_GPI_GPE_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_SMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_SMI_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_NMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_NMI_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_PADCFGLOCK,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_PADCFGLOCKTX,   R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_PADCFG_OFFSET,  GPIO_VER2_PCH_LP_GPIO_GPP_D_PAD_MAX}, //TGL PCH-LP GPP_D
+  {PID_GPIOCOM1, NO_REGISTER_FOR_PROPERTY,                   NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                     NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                         NO_REGISTER_FOR_PROPERTY,                         0},
+  {PID_GPIOCOM1, NO_REGISTER_FOR_PROPERTY,                   NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                     NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                         NO_REGISTER_FOR_PROPERTY,                         0},
+  {PID_GPIOCOM4, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_PAD_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_HOSTSW_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_GPI_IS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_GPI_GPE_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_SMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_SMI_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_NMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_NMI_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_PADCFGLOCK,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_PADCFGLOCKTX,   R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_PADCFG_OFFSET,  GPIO_VER2_PCH_LP_GPIO_GPP_C_PAD_MAX}, //TGL PCH-LP GPP_C
+  {PID_GPIOCOM4, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_PAD_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_HOSTSW_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_GPI_IS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_GPI_GPE_EN, NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_PADCFGLOCK,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_PADCFGLOCKTX,   R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_PADCFG_OFFSET,  GPIO_VER2_PCH_LP_GPIO_GPP_F_PAD_MAX}, //TGL PCH-LP GPP_F
+  {PID_GPIOCOM4, NO_REGISTER_FOR_PROPERTY,                   NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                     NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                         NO_REGISTER_FOR_PROPERTY,                         0},
+  {PID_GPIOCOM4, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_PAD_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_HOSTSW_OWN,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_GPI_IS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_GPI_GPE_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_SMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_SMI_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_NMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_NMI_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_PADCFGLOCK,  R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_PADCFGLOCKTX,   R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_PADCFG_OFFSET,  GPIO_VER2_PCH_LP_GPIO_GPP_E_PAD_MAX}, //TGL PCH-LP GPP_E
+  {PID_GPIOCOM4, NO_REGISTER_FOR_PROPERTY,                   NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                     NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                         NO_REGISTER_FOR_PROPERTY,                         0},
+  {PID_GPIOCOM3, NO_REGISTER_FOR_PROPERTY,                   NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                     NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                         NO_REGISTER_FOR_PROPERTY,                         0},
+  {PID_GPIOCOM3, NO_REGISTER_FOR_PROPERTY,                   NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                 NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                     NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,            NO_REGISTER_FOR_PROPERTY,           NO_REGISTER_FOR_PROPERTY,                      NO_REGISTER_FOR_PROPERTY,                         NO_REGISTER_FOR_PROPERTY,                         0}
+};
+
+/**
+  This procedure will retrieve address and length of GPIO info table
+
+  @param[out]  GpioGroupInfoTableLength   Length of GPIO group table
+
+  @retval Pointer to GPIO group table
+
+**/
+CONST GPIO_GROUP_INFO*
+GpioGetGroupInfoTable (
+  OUT UINT32              *GpioGroupInfoTableLength
+  )
+{
+  *GpioGroupInfoTableLength = ARRAY_SIZE (mPchLpGpioGroupInfo);
+  return mPchLpGpioGroupInfo;
+}
+
+/**
+  Get GPIO Chipset ID specific to PCH generation and series
+**/
+UINT32
+GpioGetThisChipsetId (
+  VOID
+  )
+{
+  return GPIO_VER2_LP_CHIPSET_ID;
+}
+
+/**
+  This internal procedure will check if group is within DeepSleepWell.
+
+  @param[in]  Group               GPIO Group
+
+  @retval GroupWell               TRUE:  This is DSW Group
+                                  FALSE: This is not DSW Group
+**/
+BOOLEAN
+GpioIsDswGroup (
+  IN  GPIO_GROUP         Group
+  )
+{
+  if (Group == GPIO_VER2_LP_GROUP_GPD) {
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED GPIO_GROUP_TO_GPE_MAPPING mPchLpGpioGroupToGpeMapping[] = {
+    {GPIO_VER2_LP_GROUP_GPP_B,   0, V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_B},
+    {GPIO_VER2_LP_GROUP_GPP_A,   0, V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_A},
+    {GPIO_VER2_LP_GROUP_GPP_R,   0, V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_R},
+    {GPIO_VER2_LP_GROUP_GPD,     0, V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPD  },
+    {GPIO_VER2_LP_GROUP_GPP_S,   0, V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_S},
+    {GPIO_VER2_LP_GROUP_GPP_H,   0, V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_H},
+    {GPIO_VER2_LP_GROUP_GPP_D,   0, V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_D},
+    {GPIO_VER2_LP_GROUP_GPP_C,   0, V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_C},
+    {GPIO_VER2_LP_GROUP_GPP_F,   0, V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_F},
+    {GPIO_VER2_LP_GROUP_GPP_E,   0, V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_E}
+};
+
+/**
+  Get information for GPIO Group required to program GPIO and PMC for desired 1-Tier GPE mapping
+
+  @param[out] GpioGroupToGpeMapping        Table with GPIO Group to GPE mapping
+  @param[out] GpioGroupToGpeMappingLength  GPIO Group to GPE mapping table length
+**/
+VOID
+GpioGetGroupToGpeMapping (
+  OUT GPIO_GROUP_TO_GPE_MAPPING  **GpioGroupToGpeMapping,
+  OUT UINT32                     *GpioGroupToGpeMappingLength
+  )
+{
+  *GpioGroupToGpeMapping = mPchLpGpioGroupToGpeMapping;
+  *GpioGroupToGpeMappingLength = ARRAY_SIZE (mPchLpGpioGroupToGpeMapping);
+}
+
+/**
+  Check if 0x13 opcode supported for writing to GPIO lock unlock register
+
+  @retval TRUE                It's supported
+  @retval FALSE               It's not supported
+**/
+BOOLEAN
+IsGpioLockOpcodeSupported (
+  VOID
+  )
+{
+  return TRUE;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibVer2.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibVer2.inf
new file mode 100644
index 0000000000..a355f407f8
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibVer2.inf
@@ -0,0 +1,46 @@
+## @file
+#  Component description file for the PeiDxeSmmGpioPrivateLib
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION                    = 0x00010017
+BASE_NAME                      = PeiDxeSmmGpioPrivateLibVer2
+FILE_GUID                      = 680A81B0-A087-4687-B5B4-146DA30042D6
+VERSION_STRING                 = 1.0
+MODULE_TYPE                    = BASE
+LIBRARY_CLASS                  = GpioPrivateLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
+#
+
+
+[LibraryClasses]
+  BaseLib
+  IoLib
+  DebugLib
+  PmcLib
+  PchInfoLib
+  GpioLib
+  GpioNameBufferLib
+  SataLib
+  GpioHelpersLib
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+  GpioPrivateLib.c
+  GpioPrivateLibVer2.c
+  GpioNamesVer2.c
+
+[Pcd]
+gSiPkgTokenSpaceGuid.PcdEmbeddedEnable                          ## CONSUMES
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.c
new file mode 100644
index 0000000000..84bf655ab9
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.c
@@ -0,0 +1,413 @@
+/** @file
+  This file contains routines for PEI GPIO Helpers Lib
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Library/HobLib.h>
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/GpioPrivateLib.h>
+#include <Library/GpioHelpersLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <ConfigBlock/PchGeneralConfig.h>
+#include <Ppi/SiPolicy.h>
+
+extern EFI_GUID gGpioLibUnlockHobGuid;
+
+//
+//  GPIO Lock HOB
+//  Stores information on GPIO pads that should be left unlocked
+//
+typedef struct {
+  //
+  // GPIO PadConfig unlock data
+  //
+  UINT32  PadConfig;
+  //
+  // GPIO Output unlock data
+  //
+  UINT32  OutputState;
+} GPIO_UNLOCK_HOB_DATA;
+
+/**
+  This procedure will get index of GPIO Unlock HOB structure for selected GroupIndex and DwNum.
+
+  @param[in]  GroupIndex          GPIO group index
+  @param[in]  DwNum               DWORD index for a group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+
+  @retval GpioUnlockHobIndex
+**/
+STATIC
+UINT32
+GpioUnlockDataIndex (
+  IN UINT32                       GroupIndex,
+  IN UINT32                       DwNum
+  )
+{
+  UINT32         GpioUnlockDataIndex;
+  UINT32         Index;
+
+  GpioUnlockDataIndex = 0;
+
+  for (Index = 0; Index < GroupIndex; Index++) {
+    GpioUnlockDataIndex += GPIO_GET_DW_NUM (GpioGetPadPerGroup (GpioGetGroupFromGroupIndex (Index))) + 1;
+  }
+
+  GpioUnlockDataIndex += DwNum;
+  return GpioUnlockDataIndex;
+}
+
+/**
+  This procedure will create GPIO HOB for storing unlock data
+
+  @retval Pointer to GPIO Unlock data structure
+**/
+STATIC
+GPIO_UNLOCK_HOB_DATA*
+GpioCreateUnlockData (
+  VOID
+  )
+{
+  VOID           *HobData;
+  GPIO_GROUP     Group;
+  GPIO_GROUP     GroupMin;
+  GPIO_GROUP     GroupMax;
+  UINT32         GpioUnlockDataRecords;
+
+  GroupMin = GpioGetLowestGroup ();
+  GroupMax = GpioGetHighestGroup ();
+  GpioUnlockDataRecords = 0;
+
+  for (Group = GroupMin; Group <= GroupMax; Group++) {
+    GpioUnlockDataRecords += GPIO_GET_DW_NUM (GpioGetPadPerGroup (Group)) + 1;
+  }
+
+  HobData = BuildGuidHob (&gGpioLibUnlockHobGuid, GpioUnlockDataRecords * sizeof (GPIO_UNLOCK_HOB_DATA));
+  if (HobData == NULL) {
+    return NULL;
+  }
+
+  ZeroMem (HobData, GpioUnlockDataRecords * sizeof (GPIO_UNLOCK_HOB_DATA));
+
+  return (GPIO_UNLOCK_HOB_DATA*)HobData;
+}
+
+/**
+  This procedure will Get GPIO Unlock data structure for storing unlock data.
+  If HOB doesn't exist it will be created.
+
+  @param[out] GpioUnlockData          pointer to GPIO Unlock data structure
+
+  @retval Length                      number of GPIO unlock data records
+**/
+STATIC
+UINT32
+GpioGetUnlockData (
+  GPIO_UNLOCK_HOB_DATA  **GpioUnlockData
+  )
+{
+  VOID  *Hob;
+
+  Hob = GetFirstGuidHob (&gGpioLibUnlockHobGuid);
+  if (Hob == NULL) {
+    //
+    // It is the first time this function is used so create the HOB
+    //
+    *GpioUnlockData = GpioCreateUnlockData ();
+    if (*GpioUnlockData == NULL) {
+      return 0;
+    }
+    Hob = GetFirstGuidHob (&gGpioLibUnlockHobGuid);
+  } else {
+    *GpioUnlockData = (GPIO_UNLOCK_HOB_DATA*) GET_GUID_HOB_DATA (Hob);
+  }
+  return GET_GUID_HOB_DATA_SIZE (Hob) / sizeof (GPIO_UNLOCK_HOB_DATA);
+}
+
+/**
+  This procedure will get pointer to GPIO Unlock data structure.
+
+  @param[out] GpioUnlockData          pointer to GPIO Unlock data structure
+
+  @retval Length                      number of GPIO unlock data records
+**/
+STATIC
+UINT32
+GpioLocateUnlockData (
+  GPIO_UNLOCK_HOB_DATA  **GpioUnlockData
+  )
+{
+  VOID  *Hob;
+
+  Hob = GetFirstGuidHob (&gGpioLibUnlockHobGuid);
+  if (Hob == NULL) {
+    *GpioUnlockData = NULL;
+    return 0;
+  }
+
+  *GpioUnlockData = (GPIO_UNLOCK_HOB_DATA*) GET_GUID_HOB_DATA (Hob);
+  return GET_GUID_HOB_DATA_SIZE (Hob) / sizeof (GPIO_UNLOCK_HOB_DATA);
+}
+
+/**
+  This procedure stores GPIO pad unlock information
+
+  @param[in] GpioPad         GPIO pad
+  @param[in] GpioLockConfig  GPIO Lock Configuration
+
+  @retval Status
+**/
+EFI_STATUS
+GpioStoreUnlockData (
+  IN GPIO_PAD             GpioPad,
+  IN GPIO_LOCK_CONFIG     GpioLockConfig
+  )
+{
+  GPIO_UNLOCK_HOB_DATA *GpioUnlockData;
+  UINT32               Length;
+  UINT32               GroupIndex;
+  UINT32               PadNumber;
+  UINT32               Index;
+
+  if (GpioLockConfig == GpioLockDefault) {
+    return EFI_SUCCESS;
+  }
+
+  Length = GpioGetUnlockData (&GpioUnlockData);
+  if (Length == 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  GroupIndex = GpioGetGroupIndexFromGpioPad (GpioPad);
+  PadNumber = GpioGetPadNumberFromGpioPad (GpioPad);
+  Index = GpioUnlockDataIndex (GroupIndex, GPIO_GET_DW_NUM (PadNumber));
+
+  if (Index >= Length) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((GpioLockConfig & B_GPIO_LOCK_CONFIG_PAD_CONF_LOCK_MASK) == GpioPadConfigUnlock) {
+    GpioUnlockData[Index].PadConfig |= 1 << (GpioGetPadNumberFromGpioPad (GpioPad) % 32);
+  }
+
+  if ((GpioLockConfig & B_GPIO_LOCK_CONFIG_OUTPUT_LOCK_MASK) == GpioOutputStateUnlock) {
+    GpioUnlockData[Index].OutputState |= 1 << (GpioGetPadNumberFromGpioPad (GpioPad) % 32);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure stores GPIO group data about pads which PadConfig needs to be unlocked.
+
+  @param[in]  GroupIndex          GPIO group index
+  @param[in]  DwNum               DWORD index for a group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in]  UnlockedPads        DWORD bitmask for pads which are going to be left unlocked
+                                  Bit position - PadNumber
+                                  Bit value - 0: Skip, 1: Leave unlocked
+
+  @retval Status
+**/
+EFI_STATUS
+GpioStoreGroupDwUnlockPadConfigData (
+  IN UINT32                       GroupIndex,
+  IN UINT32                       DwNum,
+  IN UINT32                       UnlockedPads
+  )
+{
+  GPIO_UNLOCK_HOB_DATA *GpioUnlockData;
+  UINT32               Length;
+  UINT32               Index;
+
+  if (UnlockedPads == 0) {
+    //
+    // No pads to be left unlocked
+    //
+    return EFI_SUCCESS;
+  }
+
+  Length = GpioGetUnlockData (&GpioUnlockData);
+  if (Length == 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  Index = GpioUnlockDataIndex (GroupIndex, DwNum);
+  if (Index >= Length) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  GpioUnlockData[Index].PadConfig |= UnlockedPads;
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure stores GPIO group data about pads which Output state needs to be unlocked.
+
+  @param[in]  GroupIndex          GPIO group index
+  @param[in]  DwNum               DWORD index for a group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @param[in]  UnlockedPads        DWORD bitmask for pads which are going to be left unlocked
+                                  Bit position - PadNumber
+                                  Bit value - 0: Skip, 1: Leave unlocked
+  @retval Status
+**/
+EFI_STATUS
+GpioStoreGroupDwUnlockOutputData (
+  IN UINT32                       GroupIndex,
+  IN UINT32                       DwNum,
+  IN UINT32                       UnlockedPads
+  )
+{
+  GPIO_UNLOCK_HOB_DATA *GpioUnlockData;
+  UINT32               Length;
+  UINT32               Index;
+
+  if (UnlockedPads == 0) {
+    //
+    // No pads to be left unlocked
+    //
+    return EFI_SUCCESS;
+  }
+
+  Length = GpioGetUnlockData (&GpioUnlockData);
+  if (Length == 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  Index = GpioUnlockDataIndex (GroupIndex, DwNum);
+  if (Index >= Length) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  GpioUnlockData[Index].OutputState |= UnlockedPads;
+  return EFI_SUCCESS;
+}
+
+/**
+  This procedure will get GPIO group data with pads, which PadConfig is supposed to be left unlock
+
+  @param[in]  GroupIndex          GPIO group index
+  @param[in]  DwNum               DWORD index for a group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @retval     UnlockedPads        DWORD bitmask for pads which are going to be left unlocked
+                                  Bit position - PadNumber
+                                  Bit value - 0: to be locked, 1: Leave unlocked
+**/
+UINT32
+GpioGetGroupDwUnlockPadConfigMask (
+  IN UINT32                       GroupIndex,
+  IN UINT32                       DwNum
+  )
+{
+  GPIO_UNLOCK_HOB_DATA *GpioUnlockData;
+  UINT32               Length;
+  UINT32               Index;
+
+  Length = GpioLocateUnlockData (&GpioUnlockData);
+  if (Length == 0) {
+    return 0;
+  }
+
+  Index = GpioUnlockDataIndex (GroupIndex, DwNum);
+  if (Index >= Length) {
+    return 0;
+  }
+
+  return GpioUnlockData[Index].PadConfig;
+}
+
+/**
+  This procedure will get GPIO group data with pads, which Output is supposed to be left unlock
+
+  @param[in]  GroupIndex          GPIO group index
+  @param[in]  DwNum               DWORD index for a group.
+                                  For group which has less then 32 pads per group DwNum must be 0.
+  @retval     UnlockedPads        DWORD bitmask for pads which are going to be left unlocked
+                                  Bit position - PadNumber
+                                  Bit value - 0: to be locked, 1: Leave unlocked
+**/
+UINT32
+GpioGetGroupDwUnlockOutputMask (
+  IN UINT32                       GroupIndex,
+  IN UINT32                       DwNum
+  )
+{
+  GPIO_UNLOCK_HOB_DATA *GpioUnlockData;
+  UINT32               Length;
+  UINT32               Index;
+
+  Length = GpioLocateUnlockData (&GpioUnlockData);
+  if (Length == 0) {
+    return 0;
+  }
+
+  Index = GpioUnlockDataIndex (GroupIndex, DwNum);
+  if (Index >= Length) {
+    return 0;
+  }
+
+  return GpioUnlockData[Index].OutputState;
+}
+
+/**
+  Obtains GpioOverride Information from PreMem config
+
+  @retval  TRUE    GPIO Override obtained successfully
+           FALSE   Unable to obtain GPIO Override data
+**/
+BOOLEAN
+STATIC
+GetGpioOverrideFromConfigBlock (
+  IN OUT  UINT8 *GpioOverride
+  )
+{
+  EFI_STATUS                   Status;
+  SI_PREMEM_POLICY_PPI         *SiPreMemPolicyPpi;
+  PCH_GENERAL_PREMEM_CONFIG    *PchGeneralPreMemConfig;
+
+  Status = PeiServicesLocatePpi (
+             &gSiPreMemPolicyPpiGuid,
+             0,
+             NULL,
+             (VOID **) &SiPreMemPolicyPpi
+             );
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+  Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gPchGeneralPreMemConfigGuid, (VOID *) &PchGeneralPreMemConfig);
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+  *GpioOverride = (UINT8) PchGeneralPreMemConfig->GpioOverride;
+
+  return TRUE;
+}
+
+/**
+  Returns Gpio Override Level1 Information
+
+  @retval  TRUE/FALSE GPIO Override Level 1 Enabled/Disabled
+**/
+BOOLEAN
+GpioOverrideLevel1Enabled (
+  VOID
+  )
+{
+  UINT8           GpioOverride;
+
+  GpioOverride = 0;
+
+  if (GetGpioOverrideFromConfigBlock (&GpioOverride)) {
+    if (GpioOverride == 1) { return TRUE; }
+  }
+
+  return FALSE;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.inf
new file mode 100644
index 0000000000..d70c2a1352
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.inf
@@ -0,0 +1,48 @@
+## @file
+# Component description file for the PeiGpioHelpersLib
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiGpioHelpersLib
+FILE_GUID = 1838E1E7-3CC4-4A74-90D9-B421EF2A579F
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = GpioHelpersLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+HobLib
+GpioLib
+PeiServicesLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PeiGpioHelpersLib.c
+
+
+[Guids]
+gGpioLibUnlockHobGuid
+gPchGeneralPreMemConfigGuid        ## CONSUMES
+
+[Ppis]
+gSiPreMemPolicyPpiGuid
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioNameBufferLib/GpioNameBufferPei.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioNameBufferLib/GpioNameBufferPei.c
new file mode 100644
index 0000000000..920d9a2cbc
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioNameBufferLib/GpioNameBufferPei.c
@@ -0,0 +1,67 @@
+/** @file
+  This file contains GpioMemLib implementation for PEI phase
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/GpioNameBufferLib.h>
+
+STATIC CONST EFI_GUID mGpioNamesPrivateHobGuid = {0x9AE3138D, 0x4EBF, 0x4E90, {0x87, 0x96, 0x11, 0xD3, 0x10, 0x04, 0x60, 0x0A}};
+
+STATIC volatile BOOLEAN mGlobalMemoryWorking = FALSE;
+
+STATIC CHAR8 mGpioNameBuffer[GPIO_NAME_LENGTH_MAX];
+
+/**
+  Returns pointer to the buffer taken from GpioLib private HOB
+
+  @retval CHAR8*  Pointer to the buffer
+**/
+STATIC
+CHAR8*
+GetBufferFromHob (
+  VOID
+  )
+{
+  VOID  *Hob;
+  CHAR8 *GpioNameBuffer;
+
+  Hob = NULL;
+  GpioNameBuffer = NULL;
+
+  Hob = GetFirstGuidHob (&mGpioNamesPrivateHobGuid);
+  if (Hob != NULL){
+    GpioNameBuffer = (CHAR8*) GET_GUID_HOB_DATA (Hob);
+  } else {
+    GpioNameBuffer = (CHAR8*) BuildGuidHob (&mGpioNamesPrivateHobGuid, GPIO_NAME_LENGTH_MAX);
+    if (GpioNameBuffer == NULL){
+      DEBUG ((DEBUG_ERROR, "Failed to setup HOB for GPIO names lib\n"));
+      ASSERT (FALSE);
+    }
+  }
+  return GpioNameBuffer;
+}
+
+/**
+  Returns pointer to the global buffer to be used by GpioNamesLib
+
+  @retval CHAR8*  Pointer to the buffer
+**/
+CHAR8*
+GpioGetStaticNameBuffer (
+  VOID
+  )
+{
+  mGlobalMemoryWorking = TRUE;
+
+  if (mGlobalMemoryWorking) {
+    return mGpioNameBuffer;
+  } else {
+    return GetBufferFromHob ();
+  }
+}
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioNameBufferLib/PeiGpioNameBufferLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioNameBufferLib/PeiGpioNameBufferLib.inf
new file mode 100644
index 0000000000..0525a42a8d
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioNameBufferLib/PeiGpioNameBufferLib.inf
@@ -0,0 +1,35 @@
+## @file
+# Component description file for the PeiGpioMemLib
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiGpioNameBufferLib
+FILE_GUID = 16EC5CA8-8195-4847-B6CB-662CDAB863F2
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = GpioNameBufferLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32
+#
+
+[LibraryClasses]
+HobLib
+BaseLib
+IoLib
+DebugLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Sources]
+GpioNameBufferPei.c
+
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 18/40] TigerlakeSiliconPkg/IpBlock: Add Graphics component
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (15 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 17/40] TigerlakeSiliconPkg/IpBlock: Add Gpio component Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 19/40] TigerlakeSiliconPkg/IpBlock: Add Hda component Heng Luo
                   ` (21 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * IpBlock/Graphics/AcpiTables
  * IpBlock/Graphics/IncludePrivate
  * IpBlock/Graphics/LibraryPrivate

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/Igfx.asl                                            | 1955 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxCommon.asl                                      |  480 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxDsm.asl                                         |  398 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxOpGbda.asl                                      |  127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxOpRn.asl                                        |  314 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxOpSbcb.asl                                      |  261 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxSsdt.asl                                        |   73 +++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxSsdt.inf                                        |   23 +++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/IncludePrivate/Library/DxeGraphicsInitLib.h                    |   53 ++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/IncludePrivate/Library/DxeGraphicsPolicyLib.h                  |   71 ++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/IncludePrivate/Library/DxeIgdOpRegionInitLib.h                 |  177 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/LibraryPrivate/DxeGraphicsInitLib/DxeGraphicsInitLib.c         |  135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/LibraryPrivate/DxeGraphicsInitLib/DxeGraphicsInitLib.inf       |   45 +++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/LibraryPrivate/DxeGraphicsPolicyLib/DxeGraphicsPolicyLib.c     |  118 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/LibraryPrivate/DxeGraphicsPolicyLib/DxeGraphicsPolicyLib.inf   |   37 +++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/LibraryPrivate/DxeIgdOpRegionInitLib/DxeIgdOpRegionInit.c      |  541 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/LibraryPrivate/DxeIgdOpRegionInitLib/DxeIgdOpRegionInitLib.inf |   49 ++++++++++++++++++++++
 17 files changed, 4857 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/Igfx.asl b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/Igfx.asl
new file mode 100644
index 0000000000..d00a1d8f58
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/Igfx.asl
@@ -0,0 +1,1955 @@
+/** @file
+  This file contains the IGD OpRegion/Software ACPI Reference
+  Code.
+  It defines the methods to enable/disable output switching,
+  store display switching and LCD brightness BIOS control
+  and return valid addresses for all display device encoders
+  present in the system, etc.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+External(\PLD1, MethodObj)
+External(\PLD2, MethodObj)
+External(\ECST, MethodObj)
+External(\PBCL, MethodObj)
+External(HDOS, MethodObj)
+External(\ECON, IntObj)
+External(\PNHM, IntObj)
+External(OSYS, IntObj)
+External(CPSC)
+External(\GUAM, MethodObj)
+External(DSEN)
+External(S0ID)
+
+//
+// Default Physical Location of Device
+//
+Name (DPLD, Package (0x1) {
+             ToPLD (
+               PLD_Revision         = 0x2,
+               PLD_IgnoreColor      = 0x1,
+               PLD_Red              = 0x0,
+               PLD_Green            = 0x0,
+               PLD_Blue             = 0x0,
+               PLD_Width            = 0x320, //800 mm
+               PLD_Height           = 0x7D0, //2000 mm
+               PLD_UserVisible      = 0x1, //Set if the device connection point can be seen by the user without disassembly.
+               PLD_Dock             = 0x0, // Set if the device connection point resides in a docking station or port replicator.
+               PLD_Lid              = 0x0, // Set if this device connection point resides on the lid of laptop system.
+               PLD_Panel              = "TOP",    // Describes which panel surface of the systems housing the device connection point resides on.
+               PLD_VerticalPosition   = "CENTER", // Vertical Position on the panel where the device connection point resides.
+               PLD_HorizontalPosition = "RIGHT",  // Horizontal Position on the panel where the device connection point resides.
+               PLD_Shape              = "VERTICALRECTANGLE",
+               PLD_GroupOrientation = 0x0, // if Set, indicates vertical grouping, otherwise horizontal is assumed.
+               PLD_GroupToken       = 0x0, // Unique numerical value identifying a group.
+               PLD_GroupPosition    = 0x0, // Identifies this device connection points position in the group (i.e. 1st, 2nd)
+               PLD_Bay              = 0x0, // Set if describing a device in a bay or if device connection point is a bay.
+               PLD_Ejectable        = 0x0, // Set if the device is ejectable. Indicates ejectability in the absence of _EJx objects
+               PLD_EjectRequired    = 0x0, // OSPM Ejection required: Set if OSPM needs to be involved with ejection process. User-operated physical hardware ejection is not possible.
+               PLD_CabinetNumber    = 0x0, // For single cabinet system, this field is always 0.
+               PLD_CardCageNumber   = 0x0, // For single card cage system, this field is always 0.
+               PLD_Reference        = 0x0, // if Set, this _PLD defines a reference shape that is used to help orient the user with respect to the other shapes when rendering _PLDs.
+               PLD_Rotation         = 0x0, // 0 - 0deg, 1 - 45deg, 2 - 90deg, 3 - 135deg, 4 - 180deg, 5 - 225deg, 6 - 270deg, 7 - 315deg
+               PLD_Order            = 0x3, // Identifies the drawing order of the connection point described by a _PLD
+               PLD_VerticalOffset   = 0x0,
+               PLD_HorizontalOffset = 0x0
+              )
+            } // Package
+) //DPLD
+
+// Enable/Disable Output Switching.  In WIN2K/WINXP, _DOS = 0 will
+// get called during initialization to prepare for an ACPI Display
+// Switch Event.  During an ACPI Display Switch, the OS will call
+// _DOS = 2 immediately after a Notify=0x80 to temporarily disable
+// all Display Switching.  After ACPI Display Switching is complete,
+// the OS will call _DOS = 0 to re-enable ACPI Display Switching.
+Method(_DOS,1)
+{
+  //
+  // Store Display Switching and LCD brightness BIOS control bit
+  //
+  Store(And(Arg0,7),DSEN)
+
+  If(LEqual(And(Arg0,  0x3), 0))     // If _DOS[1:0]=0
+  {
+    If(CondRefOf(HDOS))
+    {
+      HDOS()
+    }
+  }
+}
+
+//
+// Enumerate the Display Environment.  This method will return
+// valid addresses for all display device encoders present in the
+// system.  The Miniport Driver will reject the addresses for every
+// encoder that does not have an attached display device.  After
+// enumeration is complete, the OS will call the _DGS methods
+// during a display switch only for the addresses accepted by the
+// Miniport Driver.  For hot-insertion and removal of display
+// devices, a re-enumeration notification will be required so the
+// address of the newly present display device will be accepted by
+// the Miniport Driver.
+//
+Method(_DOD,0)
+{
+  //
+  // Two LFP devices are supporte by default
+  //
+  Store(2, NDID)
+  If(LNotEqual(DIDL, Zero))
+  {
+    Store(SDDL(DIDL),DID1)
+  }
+  If(LNotEqual(DDL2, Zero))
+  {
+    Store(SDDL(DDL2),DID2)
+  }
+  If(LNotEqual(DDL3, Zero))
+  {
+    Store(SDDL(DDL3),DID3)
+  }
+  If(LNotEqual(DDL4, Zero))
+  {
+    Store(SDDL(DDL4),DID4)
+  }
+  If(LNotEqual(DDL5, Zero))
+  {
+    Store(SDDL(DDL5),DID5)
+  }
+  If(LNotEqual(DDL6, Zero))
+  {
+    Store(SDDL(DDL6),DID6)
+  }
+  If(LNotEqual(DDL7, Zero))
+  {
+    Store(SDDL(DDL7),DID7)
+  }
+  If(LNotEqual(DDL8, Zero))
+  {
+    Store(SDDL(DDL8),DID8)
+  }
+  If(LNotEqual(DDL9, Zero))
+  {
+    Store(SDDL(DDL9),DID9)
+  }
+  If(LNotEqual(DD10, Zero))
+  {
+    Store(SDDL(DD10),DIDA)
+  }
+  If(LNotEqual(DD11, Zero))
+  {
+    Store(SDDL(DD11),DIDB)
+  }
+  If(LNotEqual(DD12, Zero))
+  {
+    Store(SDDL(DD12),DIDC)
+  }
+  If(LNotEqual(DD13, Zero))
+  {
+    Store(SDDL(DD13),DIDD)
+  }
+  If(LNotEqual(DD14, Zero))
+  {
+    Store(SDDL(DD14),DIDE)
+  }
+  If(LNotEqual(DD15, Zero))
+  {
+    Store(SDDL(DD15),DIDF)
+  }
+
+  //
+  // Enumerate the encoders. Note that for
+  // current silicon, the maximum number of encoders
+  // possible is 15.
+  //
+  If(LEqual(NDID,1))
+  {
+    Name(TMP1,Package() {
+          0xFFFFFFFF})
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMP1,0))
+    } Else {
+      Store(Or(0x10000,DID1),Index(TMP1,0))
+    }
+    Return(TMP1)
+  }
+
+  If(LEqual(NDID,2))
+  {
+    Name(TMP2,Package() {
+          0xFFFFFFFF,
+          0xFFFFFFFF})
+    Store(Or(0x10000,DID1),Index(TMP2,0))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMP2,1))
+    } Else {
+      Store(Or(0x10000,DID2),Index(TMP2,1))
+    }
+    Return(TMP2)
+  }
+
+  If(LEqual(NDID,3))
+  {
+    Name(TMP3,Package() {
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF})
+    Store(Or(0x10000,DID1),Index(TMP3,0))
+    Store(Or(0x10000,DID2),Index(TMP3,1))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMP3,2))
+    } Else {
+      Store(Or(0x10000,DID3),Index(TMP3,2))
+    }
+    Return(TMP3)
+  }
+
+  If(LEqual(NDID,4))
+  {
+    Name(TMP4,Package() {
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF})
+    Store(Or(0x10000,DID1),Index(TMP4,0))
+    Store(Or(0x10000,DID2),Index(TMP4,1))
+    Store(Or(0x10000,DID3),Index(TMP4,2))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMP4,3))
+    } Else {
+      Store(Or(0x10000,DID4),Index(TMP4,3))
+    }
+    Return(TMP4)
+  }
+
+  If(LEqual(NDID,5))
+  {
+    Name(TMP5,Package() {
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF})
+    Store(Or(0x10000,DID1),Index(TMP5,0))
+    Store(Or(0x10000,DID2),Index(TMP5,1))
+    Store(Or(0x10000,DID3),Index(TMP5,2))
+    Store(Or(0x10000,DID4),Index(TMP5,3))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMP5,4))
+    } Else {
+      Store(Or(0x10000,DID5),Index(TMP5,4))
+    }
+    Return(TMP5)
+  }
+
+  If(LEqual(NDID,6))
+  {
+    Name(TMP6,Package() {
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF})
+    Store(Or(0x10000,DID1),Index(TMP6,0))
+    Store(Or(0x10000,DID2),Index(TMP6,1))
+    Store(Or(0x10000,DID3),Index(TMP6,2))
+    Store(Or(0x10000,DID4),Index(TMP6,3))
+    Store(Or(0x10000,DID5),Index(TMP6,4))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMP6,5))
+    } Else {
+      Store(Or(0x10000,DID6),Index(TMP6,5))
+    }
+    Return(TMP6)
+  }
+
+  If(LEqual(NDID,7))
+  {
+    Name(TMP7,Package() {
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF})
+    Store(Or(0x10000,DID1),Index(TMP7,0))
+    Store(Or(0x10000,DID2),Index(TMP7,1))
+    Store(Or(0x10000,DID3),Index(TMP7,2))
+    Store(Or(0x10000,DID4),Index(TMP7,3))
+    Store(Or(0x10000,DID5),Index(TMP7,4))
+    Store(Or(0x10000,DID6),Index(TMP7,5))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMP7,6))
+    } Else {
+      Store(Or(0x10000,DID7),Index(TMP7,6))
+    }
+    Return(TMP7)
+  }
+
+  If(LEqual(NDID,8))
+  {
+    Name(TMP8,Package() {
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF})
+    Store(Or(0x10000,DID1),Index(TMP8,0))
+    Store(Or(0x10000,DID2),Index(TMP8,1))
+    Store(Or(0x10000,DID3),Index(TMP8,2))
+    Store(Or(0x10000,DID4),Index(TMP8,3))
+    Store(Or(0x10000,DID5),Index(TMP8,4))
+    Store(Or(0x10000,DID6),Index(TMP8,5))
+    Store(Or(0x10000,DID7),Index(TMP8,6))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMP8,7))
+    } Else {
+      Store(Or(0x10000,DID8),Index(TMP8,7))
+    }
+    Return(TMP8)
+  }
+
+  If(LEqual(NDID,9))
+  {
+    Name(TMP9,Package() {
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF})
+    Store(Or(0x10000,DID1),Index(TMP9,0))
+    Store(Or(0x10000,DID2),Index(TMP9,1))
+    Store(Or(0x10000,DID3),Index(TMP9,2))
+    Store(Or(0x10000,DID4),Index(TMP9,3))
+    Store(Or(0x10000,DID5),Index(TMP9,4))
+    Store(Or(0x10000,DID6),Index(TMP9,5))
+    Store(Or(0x10000,DID7),Index(TMP9,6))
+    Store(Or(0x10000,DID8),Index(TMP9,7))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMP9,8))
+    } Else {
+      Store(Or(0x10000,DID9),Index(TMP9,8))
+    }
+    Return(TMP9)
+  }
+
+  If(LEqual(NDID,0x0A))
+  {
+    Name(TMPA,Package() {
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF})
+    Store(Or(0x10000,DID1),Index(TMPA,0))
+    Store(Or(0x10000,DID2),Index(TMPA,1))
+    Store(Or(0x10000,DID3),Index(TMPA,2))
+    Store(Or(0x10000,DID4),Index(TMPA,3))
+    Store(Or(0x10000,DID5),Index(TMPA,4))
+    Store(Or(0x10000,DID6),Index(TMPA,5))
+    Store(Or(0x10000,DID7),Index(TMPA,6))
+    Store(Or(0x10000,DID8),Index(TMPA,7))
+    Store(Or(0x10000,DID9),Index(TMPA,8))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMPA,9))
+    } Else {
+      Store(Or(0x10000,DIDA),Index(TMPA,9))
+    }
+    Return(TMPA)
+  }
+
+  If(LEqual(NDID,0x0B))
+  {
+    Name(TMPB,Package() {
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF})
+    Store(Or(0x10000,DID1),Index(TMPB,0))
+    Store(Or(0x10000,DID2),Index(TMPB,1))
+    Store(Or(0x10000,DID3),Index(TMPB,2))
+    Store(Or(0x10000,DID4),Index(TMPB,3))
+    Store(Or(0x10000,DID5),Index(TMPB,4))
+    Store(Or(0x10000,DID6),Index(TMPB,5))
+    Store(Or(0x10000,DID7),Index(TMPB,6))
+    Store(Or(0x10000,DID8),Index(TMPB,7))
+    Store(Or(0x10000,DID9),Index(TMPB,8))
+    Store(Or(0x10000,DIDA),Index(TMPB,9))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMPB,10))
+    } Else {
+      Store(Or(0x10000,DIDB),Index(TMPB,10))
+    }
+    Return(TMPB)
+  }
+
+  If(LEqual(NDID,0x0C))
+  {
+    Name(TMPC,Package() {
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF})
+    Store(Or(0x10000,DID1),Index(TMPC,0))
+    Store(Or(0x10000,DID2),Index(TMPC,1))
+    Store(Or(0x10000,DID3),Index(TMPC,2))
+    Store(Or(0x10000,DID4),Index(TMPC,3))
+    Store(Or(0x10000,DID5),Index(TMPC,4))
+    Store(Or(0x10000,DID6),Index(TMPC,5))
+    Store(Or(0x10000,DID7),Index(TMPC,6))
+    Store(Or(0x10000,DID8),Index(TMPC,7))
+    Store(Or(0x10000,DID9),Index(TMPC,8))
+    Store(Or(0x10000,DIDA),Index(TMPC,9))
+    Store(Or(0x10000,DIDB),Index(TMPC,10))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMPC,11))
+    } Else {
+      Store(Or(0x10000,DIDC),Index(TMPC,11))
+    }
+    Return(TMPC)
+  }
+
+  If(LEqual(NDID,0x0D))
+  {
+    Name(TMPD,Package() {
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF})
+    Store(Or(0x10000,DID1),Index(TMPD,0))
+    Store(Or(0x10000,DID2),Index(TMPD,1))
+    Store(Or(0x10000,DID3),Index(TMPD,2))
+    Store(Or(0x10000,DID4),Index(TMPD,3))
+    Store(Or(0x10000,DID5),Index(TMPD,4))
+    Store(Or(0x10000,DID6),Index(TMPD,5))
+    Store(Or(0x10000,DID7),Index(TMPD,6))
+    Store(Or(0x10000,DID8),Index(TMPD,7))
+    Store(Or(0x10000,DID9),Index(TMPD,8))
+    Store(Or(0x10000,DIDA),Index(TMPD,9))
+    Store(Or(0x10000,DIDB),Index(TMPD,10))
+    Store(Or(0x10000,DIDC),Index(TMPD,11))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMPD,12))
+    } Else {
+      Store(Or(0x10000,DIDD),Index(TMPD,12))
+    }
+    Return(TMPD)
+  }
+
+  If(LEqual(NDID,0x0E))
+  {
+    Name(TMPE,Package() {
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF})
+    Store(Or(0x10000,DID1),Index(TMPE,0))
+    Store(Or(0x10000,DID2),Index(TMPE,1))
+    Store(Or(0x10000,DID3),Index(TMPE,2))
+    Store(Or(0x10000,DID4),Index(TMPE,3))
+    Store(Or(0x10000,DID5),Index(TMPE,4))
+    Store(Or(0x10000,DID6),Index(TMPE,5))
+    Store(Or(0x10000,DID7),Index(TMPE,6))
+    Store(Or(0x10000,DID8),Index(TMPE,7))
+    Store(Or(0x10000,DID9),Index(TMPE,8))
+    Store(Or(0x10000,DIDA),Index(TMPE,9))
+    Store(Or(0x10000,DIDB),Index(TMPE,10))
+    Store(Or(0x10000,DIDC),Index(TMPE,11))
+    Store(Or(0x10000,DIDD),Index(TMPE,12))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMPE,13))
+    } Else {
+      Store(Or(0x10000,DIDE),Index(TMPE,13))
+    }
+    Return(TMPE)
+  }
+
+  If(LEqual(NDID,0x0F))
+  {
+    Name(TMPF,Package() {
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF})
+    Store(Or(0x10000,DID1),Index(TMPF,0))
+    Store(Or(0x10000,DID2),Index(TMPF,1))
+    Store(Or(0x10000,DID3),Index(TMPF,2))
+    Store(Or(0x10000,DID4),Index(TMPF,3))
+    Store(Or(0x10000,DID5),Index(TMPF,4))
+    Store(Or(0x10000,DID6),Index(TMPF,5))
+    Store(Or(0x10000,DID7),Index(TMPF,6))
+    Store(Or(0x10000,DID8),Index(TMPF,7))
+    Store(Or(0x10000,DID9),Index(TMPF,8))
+    Store(Or(0x10000,DIDA),Index(TMPF,9))
+    Store(Or(0x10000,DIDB),Index(TMPF,10))
+    Store(Or(0x10000,DIDC),Index(TMPF,11))
+    Store(Or(0x10000,DIDD),Index(TMPF,12))
+    Store(Or(0x10000,DIDE),Index(TMPF,13))
+    If (LEqual(IPTP,1)) {
+      //
+      // IGFX need report IPUA as GFX0 child
+      //
+      Store(0x00023480,Index(TMPF,14))
+    } Else {
+      Store(Or(0x10000,DIDF),Index(TMPF,14))
+    }
+    Return(TMPF)
+  }
+
+  If(LEqual(NDID,0x10))
+  {
+    Name(TMPG,Package() {
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF,
+          0xFFFFFFFF})
+    Store(Or(0x10000,DID1),Index(TMPG,0))
+    Store(Or(0x10000,DID2),Index(TMPG,1))
+    Store(Or(0x10000,DID3),Index(TMPG,2))
+    Store(Or(0x10000,DID4),Index(TMPG,3))
+    Store(Or(0x10000,DID5),Index(TMPG,4))
+    Store(Or(0x10000,DID6),Index(TMPG,5))
+    Store(Or(0x10000,DID7),Index(TMPG,6))
+    Store(Or(0x10000,DID8),Index(TMPG,7))
+    Store(Or(0x10000,DID9),Index(TMPG,8))
+    Store(Or(0x10000,DIDA),Index(TMPG,9))
+    Store(Or(0x10000,DIDB),Index(TMPG,10))
+    Store(Or(0x10000,DIDC),Index(TMPG,11))
+    Store(Or(0x10000,DIDD),Index(TMPG,12))
+    Store(Or(0x10000,DIDE),Index(TMPG,13))
+    Store(Or(0x10000,DIDF),Index(TMPG,14))
+    //
+    // IGFX need report IPUA as GFX0 child
+    // NDID can only be 0x10 if IPU is enabled
+    //
+    Store(0x00023480,Index(TMPG,15))
+    Return(TMPG)
+  }
+
+  //
+  // If nothing else, return Unknown LFP.
+  // (Prevents compiler warning.)
+  //
+  Return(Package() {0x00000400})
+}
+
+Device(DD01)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID1),0x400))
+    {
+      Store(0x1, EDPV)
+      Store(NXD1, NXDX)
+      Store(DID1, DIDX)
+      Return(1)
+    }
+    If(LEqual(DID1,0))
+    {
+      Return(1)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DID1))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    Return(CDDS(DID1))
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(HGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD1)
+    }
+    Return(NDDS(DID1))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD02)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID2),0x400))
+    {
+      If(LEqual(And(0xF,DID2),0x1))
+      {
+        Store(0x2, EDPV)
+        Store(NXD2, NXDY)
+        Store(DID2, DIDY)
+        Return(2)
+      }
+      Store(0x2, EDPV)
+      Store(NXD2, NXDX)
+      Store(DID2, DIDX)
+      Return(2)
+    }
+    If(LEqual(DID2,0))
+    {
+      Return(2)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DID2))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(LIDS,0))
+    {
+      Return(0x0)
+    }
+    Return(CDDS(DID2))
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    //
+    // Return the Next State.
+    //
+    If(LAnd(LEqual(And(HGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD2)
+    }
+    Return(NDDS(DID2))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD03)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID3),0x400))
+    {
+      Store(0x3, EDPV)
+      Store(NXD3, NXDX)
+      Store(DID3, DIDX)
+      Return(3)
+    }
+    If(LEqual(DID3,0))
+    {
+      Return(3)
+    }
+    Else
+    {
+    Return(And(0xFFFF,DID3))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DID3,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(CDDS(DID3))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(HGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD3)
+    }
+    Return(NDDS(DID3))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD04)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID4),0x400))
+    {
+      Store(0x4, EDPV)
+      Store(NXD4, NXDX)
+      Store(DID4, DIDX)
+      Return(4)
+    }
+    If(LEqual(DID4,0))
+    {
+      Return(4)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DID4))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DID4,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(CDDS(DID4))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(HGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD4)
+    }
+    Return(NDDS(DID4))
+  }
+
+  //
+  // Device Set State. (See table above.)
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD05)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID5),0x400))
+    {
+      Store(0x5, EDPV)
+      Store(NXD5, NXDX)
+      Store(DID5, DIDX)
+      Return(5)
+    }
+    If(LEqual(DID5,0))
+    {
+      Return(5)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DID5))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DID5,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(CDDS(DID5))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(HGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD5)
+    }
+    Return(NDDS(DID5))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD06)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID6),0x400))
+    {
+      Store(0x6, EDPV)
+      Store(NXD6, NXDX)
+      Store(DID6, DIDX)
+      Return(6)
+    }
+    If(LEqual(DID6,0))
+    {
+      Return(6)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DID6))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DID6,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(CDDS(DID6))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(HGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD6)
+    }
+    Return(NDDS(DID6))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD07)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID7),0x400))
+    {
+      Store(0x7, EDPV)
+      Store(NXD7, NXDX)
+      Store(DID7, DIDX)
+      Return(7)
+    }
+    If(LEqual(DID7,0))
+    {
+      Return(7)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DID7))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DID7,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(CDDS(DID7))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(HGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD7)
+    }
+    Return(NDDS(DID7))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD08)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID8),0x400))
+    {
+      Store(0x8, EDPV)
+      Store(NXD8, NXDX)
+      Store(DID8, DIDX)
+      Return(8)
+    }
+    If(LEqual(DID8,0))
+    {
+      Return(8)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DID8))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DID8,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(CDDS(DID8))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(HGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD8)
+    }
+    Return(NDDS(DID8))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD09)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DID9),0x400))
+    {
+      Store(0x9, EDPV)
+      Store(NXD8, NXDX)
+      Store(DID9, DIDX)
+      Return(9)
+    }
+    If(LEqual(DID9,0))
+    {
+      Return(9)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DID9))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DID9,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(CDDS(DID9))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(HGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD8)
+    }
+    Return(NDDS(DID9))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD0A)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DIDA),0x400))
+    {
+      Store(0xA, EDPV)
+      Store(NXD8, NXDX)
+      Store(DIDA, DIDX)
+      Return(0x0A)
+    }
+    If(LEqual(DIDA,0))
+    {
+      Return(0x0A)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DIDA))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DIDA,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(CDDS(DIDA))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(HGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD8)
+    }
+    Return(NDDS(DIDA))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD0B)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DIDB),0x400))
+    {
+      Store(0xB, EDPV)
+      Store(NXD8, NXDX)
+      Store(DIDB, DIDX)
+      Return(0X0B)
+    }
+    If(LEqual(DIDB,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DIDB))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DIDB,0))
+    {
+      Return(0x0B)
+    }
+    Else
+    {
+      Return(CDDS(DIDB))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(HGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD8)
+    }
+    Return(NDDS(DIDB))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD0C)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DIDC),0x400))
+    {
+      Store(0xC, EDPV)
+      Store(NXD8, NXDX)
+      Store(DIDC, DIDX)
+      Return(0X0C)
+    }
+    If(LEqual(DIDC,0))
+    {
+      Return(0x0C)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DIDC))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DIDC,0))
+    {
+      Return(0x0C)
+    }
+    Else
+    {
+      Return(CDDS(DIDC))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(HGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD8)
+    }
+    Return(NDDS(DIDC))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD0D)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DIDD),0x400))
+    {
+      Store(0xD, EDPV)
+      Store(NXD8, NXDX)
+      Store(DIDD, DIDX)
+      Return(0X0D)
+    }
+    If(LEqual(DIDD,0))
+    {
+      Return(0x0D)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DIDD))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DIDD,0))
+    {
+      Return(0x0D)
+    }
+    Else
+    {
+      Return(CDDS(DIDD))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(HGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD8)
+    }
+    Return(NDDS(DIDD))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD0E)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DIDE),0x400))
+    {
+      Store(0xE, EDPV)
+      Store(NXD8, NXDX)
+      Store(DIDE, DIDX)
+      Return(0X0E)
+    }
+    If(LEqual(DIDE,0))
+    {
+      Return(0x0E)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DIDE))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DIDE,0))
+    {
+      Return(0x0E)
+    }
+    Else
+    {
+      Return(CDDS(DIDE))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(HGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD8)
+    }
+    Return(NDDS(DIDE))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+Device(DD0F)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(And(0x0F00,DIDF),0x400))
+    {
+      Store(0xF, EDPV)
+      Store(NXD8, NXDX)
+      Store(DIDF, DIDX)
+      Return(0X0F)
+    }
+    If(LEqual(DIDF,0))
+    {
+      Return(0x0F)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DIDF))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(DIDC,0))
+    {
+      Return(0x0F)
+    }
+    Else
+    {
+      Return(CDDS(DIDF))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(HGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXD8)
+    }
+    Return(NDDS(DIDF))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+}
+
+//
+//Device for eDP
+//
+Device(DD1F)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(EDPV, 0x0))
+    {
+      Return(0x1F)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DIDX))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(EDPV, 0x0))
+    {
+      Return(0x00)
+    }
+    Else
+    {
+      Return(CDDS(DIDX))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(HGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXDX)
+    }
+    Return(NDDS(DIDX))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+
+  //
+  // Query List of Brightness Control Levels Supported.
+  //
+  Method(_BCL,0)
+  {
+    //
+    // List of supported brightness levels in the following sequence.
+    // Level when machine has full power.
+    // Level when machine is on batteries.
+    // Other supported levels.
+    //
+    If(CondRefOf(\PBCL)) {
+      Return (PBCL())
+    } Else {
+      Return(Package(){80, 50, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100})
+    }
+  }
+
+  //
+  // Set the Brightness Level.
+  //
+  Method (_BCM,1)
+  {
+    //
+    // Set the requested level if it is between 0 and 100%.
+    //
+    If(LAnd(LGreaterEqual(Arg0,0),LLessEqual(Arg0,100)))
+    {
+      \_SB.PC00.GFX0.AINT(1, Arg0)
+      Store(Arg0,BRTL)  // Store Brightness Level.
+    }
+  }
+
+  //
+  // Brightness Query Current level.
+  //
+  Method (_BQC,0)
+  {
+    Return(BRTL)
+  }
+
+  //
+  // Physical Location of Device
+  //
+  Method (_PLD,0)
+  {
+    If(CondRefOf(\PLD1)) {
+      Return (PLD1())
+    } Else {
+      Return (DPLD)
+    }
+  }
+}
+
+//
+// Second Display
+//
+Device(DD2F)
+{
+  //
+  // Return Unique ID.
+  //
+  Method(_ADR,0,Serialized)
+  {
+    If(LEqual(EDPV, 0x0))
+    {
+      Return(0x1F)
+    }
+    If(LEqual(EDPV, 0x1))
+    {
+      Return(0x1F)
+    }
+    Else
+    {
+      Return(And(0xFFFF,DIDY))
+    }
+  }
+
+  //
+  // Return the Current Status.
+  //
+  Method(_DCS,0)
+  {
+    If(LEqual(EDPV, 0x0))
+    {
+      Return(0x00)
+    }
+    If(LEqual(EDPV, 0x1))
+    {
+      Return(0x0)
+    }
+    Else
+    {
+      Return(CDDS(DIDY))
+    }
+  }
+
+  //
+  // Query Graphics State (active or inactive).
+  //
+  Method(_DGS,0)
+  {
+    If(LAnd(LEqual(And(HGMD,0x7F),0x01),CondRefOf(SNXD)))
+    {
+      Return (NXDY)
+    }
+    Return(NDDS(DIDY))
+  }
+
+  //
+  // Device Set State.
+  //
+  Method(_DSS,1)
+  {
+    DSST(Arg0)
+  }
+
+  //
+  // Query List of Brightness Control Levels Supported.
+  //
+  Method(_BCL,0)
+  {
+    //
+    // List of supported brightness levels in the following sequence.
+    // Level when machine has full power.
+    // Level when machine is on batteries.
+    // Other supported levels.
+    //
+    If(CondRefOf(\PBCL)) {
+      Return (PBCL())
+    } Else {
+      Return(Package(){80, 50, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100})
+    }
+  }
+
+  //
+  // Set the Brightness Level.
+  //
+  Method (_BCM,1)
+  {
+    //
+    // Set the requested level if it is between 0 and 100%.
+    //
+    If(LAnd(LGreaterEqual(Arg0,0),LLessEqual(Arg0,100)))
+    {
+      \_SB.PC00.GFX0.AINT(1, Arg0)
+      Store(Arg0,BRTL)  // Store Brightness Level.
+    }
+  }
+
+  //
+  // Brightness Query Current level.
+  //
+  Method (_BQC,0)
+  {
+    Return(BRTL)
+  }
+
+  Method (_PLD,0)
+  {
+    If(CondRefOf(\PLD2)) {
+      Return (PLD2())
+    } Else {
+      Return (DPLD)
+    }
+  }
+}
+
+Method(SDDL,1)
+{
+  Increment(NDID)
+  Store(And(Arg0,0xF0F),Local0)
+  Or(0x80000000,Local0, Local1)
+  If(LEqual(DIDL,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DDL2,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DDL3,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DDL4,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DDL5,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DDL6,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DDL7,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DDL8,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DDL9,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DD10,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DD11,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DD12,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DD13,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DD14,Local0))
+  {
+    Return(Local1)
+  }
+  If(LEqual(DD15,Local0))
+  {
+    Return(Local1)
+  }
+  Return(0)
+}
+
+Method(CDDS,1)
+{
+  Store(And(Arg0,0xF0F),Local0)
+
+  If(LEqual(0, Local0))
+  {
+    Return(0x1D)
+  }
+  If(LEqual(CADL, Local0))
+  {
+    Return(0x1F)
+  }
+  If(LEqual(CAL2, Local0))
+  {
+    Return(0x1F)
+  }
+  If(LEqual(CAL3, Local0))
+  {
+    Return(0x1F)
+  }
+  If(LEqual(CAL4, Local0))
+  {
+    Return(0x1F)
+  }
+  If(LEqual(CAL5, Local0))
+  {
+    Return(0x1F)
+  }
+  If(LEqual(CAL6, Local0))
+  {
+    Return(0x1F)
+  }
+  If(LEqual(CAL7, Local0))
+  {
+    Return(0x1F)
+  }
+  If(LEqual(CAL8, Local0))
+  {
+    Return(0x1F)
+  }
+  Return(0x1D)
+}
+
+Method(NDDS,1)
+{
+  Store(And(Arg0,0xF0F),Local0)
+
+  If(LEqual(0, Local0))
+  {
+    Return(0)
+  }
+  If(LEqual(NADL, Local0))
+  {
+    Return(1)
+  }
+  If(LEqual(NDL2, Local0))
+  {
+    Return(1)
+  }
+  If(LEqual(NDL3, Local0))
+  {
+    Return(1)
+  }
+  If(LEqual(NDL4, Local0))
+  {
+    Return(1)
+  }
+  If(LEqual(NDL5, Local0))
+  {
+    Return(1)
+  }
+  If(LEqual(NDL6, Local0))
+  {
+    Return(1)
+  }
+  If(LEqual(NDL7, Local0))
+  {
+    Return(1)
+  }
+  If(LEqual(NDL8, Local0))
+  {
+    Return(1)
+  }
+  Return(0)
+}
+
+//
+// Device Set State Table
+//  BIT31  BIT30  Execution
+//  0  0  Don't implement.
+//  0  1  Cache change.  Nothing to Implement.
+//  1  0  Don't Implement.
+//  1  1  Display Switch Complete.  Implement.
+//
+Method(DSST,1)
+{
+  If(LEqual(And(Arg0,0xC0000000),0xC0000000))
+  {
+    //
+    // State change was performed by the
+    // Video Drivers.  Simply update the
+    // New State.
+    //
+    Store(NSTE,CSTE)
+  }
+}
+
+//
+// Include IGD OpRegion/Software SCI interrupt handler/DSM which is used by
+// the graphics drivers to request data from system BIOS.
+//
+include ("IgfxOpRn.asl")
+include ("IgfxDsm.asl")
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxCommon.asl b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxCommon.asl
new file mode 100644
index 0000000000..7325b9fdea
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxCommon.asl
@@ -0,0 +1,480 @@
+/** @file
+  IGD OpRegion/Software SCI Reference Code.
+  This file contains ASL code with the purpose of handling events
+  i.e. hotkeys and other system interrupts.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+//
+// Notes:
+// 1. The following routines are to be called from the appropriate event
+//    handlers.
+// 2. This code cannot comprehend the exact implementation in the OEM's BIOS.
+//    Therefore, an OEM must call these methods from the existing event
+//    handler infrastructure.  Details on when/why to call each method is
+//    included in the method header under the "usage" section.
+//
+
+/************************************************************************;
+;* ACPI Notification Methods
+;************************************************************************/
+
+
+/************************************************************************;
+;*
+;* Name:        PDRD
+;*
+;* Description: Check if the graphics driver is ready to process
+;*              notifications and video extensions.
+;*
+;* Usage:       This method is to be called prior to performing any
+;*              notifications or handling video extensions.
+;*              Ex: If (PDRD()) {Return (FAIL)}
+;*
+;* Input:       None
+;*
+;* Output:      None
+;*
+;* References:  DRDY (Driver ready status), ASLP (Driver recommended
+;*              sleep timeout value).
+;*
+;************************************************************************/
+
+External(HNOT, MethodObj)
+
+Method(PDRD)
+{
+  //
+  // If DRDY is clear, the driver is not ready.  If the return value is
+  // !=0, do not perform any notifications or video extension handling.
+  //
+  Return(LNot(DRDY))
+}
+
+/************************************************************************;
+;*
+;* Name:        PSTS
+;*
+;* Description: Check if the graphics driver has completed the previous
+;*              "notify" command.
+;*
+;* Usage:       This method is called before every "notify" command.  A
+;*              "notify" should only be set if the driver has completed the
+;*              previous command.  Else, ignore the event and exit the parent
+;*              method.
+;*              Ex: If (PSTS()) {Return (FAIL)}
+;*
+;* Input:       None
+;*
+;* Output:      None
+;*
+;* References:  CSTS (Notification status), ASLP (Driver recommended sleep
+;*              timeout value).
+;*
+;************************************************************************/
+
+Method(PSTS)
+{
+  If(LGreater(CSTS, 2))
+  {
+    //
+    // Sleep for ASLP milliseconds if the status is not "success,
+    // failure, or pending"
+    //
+    Sleep(ASLP)
+  }
+
+  Return(LEqual(CSTS, 3)) // Return True if still Dispatched
+}
+
+/************************************************************************;
+;*
+;* Name:  GNOT
+;*
+;* Description: Call the appropriate methods to query the graphics driver
+;*              status.  If all methods return success, do a notification of
+;*              the graphics device.
+;*
+;* Usage:       This method is to be called when a graphics device
+;*              notification is required (display switch hotkey, etc).
+;*
+;* Input:       Arg0 = Current event type:
+;*                1 = display switch
+;*                2 = lid
+;*                3 = dock
+;*              Arg1 = Notification type:
+;*                0 = Re-enumeration
+;*                0x80 = Display switch
+;*
+;* Output:      Returns 0 = success, 1 = failure
+;*
+;* References:  PDRD and PSTS methods.  OSYS (OS version)
+;*
+;************************************************************************/
+
+Method(GNOT, 2)
+{
+  //
+  // Check for 1. Driver loaded, 2. Driver ready.
+  // If any of these cases is not met, skip this event and return failure.
+  //
+  If(PDRD())
+  {
+    Return(0x1) // Return failure if driver not loaded.
+  }
+
+  Store(Arg0, CEVT) // Set up the current event value
+  Store(3, CSTS) // CSTS=BIOS dispatched an event
+
+  If(LAnd(LEqual(CHPD, 0), LEqual(Arg1, 0))) // Do not re-enum if driver supports hotplug
+  {
+    //
+    // Re-enumerate the Graphics Device for non-XP operating systems.
+    //
+    Notify(\_SB.PC00.GFX0, Arg1)
+  }
+
+  If(CondRefOf(HNOT))
+  {
+    HNOT(Arg0)  //Notification handler for Hybrid graphics
+  }
+  Else
+  {
+    Notify(\_SB.PC00.GFX0,0x80)
+  }
+
+  Return(0x0) // Return success
+}
+
+/************************************************************************;
+;*
+;* Name:        GHDS
+;*
+;* Description: Handle a hotkey display switching event (performs a
+;*              Notify(GFX0, 0).
+;*
+;* Usage:       This method must be called when a hotkey event occurs and the
+;*              purpose of that hotkey is to do a display switch.
+;*
+;* Input:       Arg0 = Toggle table number.
+;*
+;* Output:      Returns 0 = success, 1 = failure.
+;*              CEVT and TIDX are indirect outputs.
+;*
+;* References:  TIDX, GNOT
+;*
+;************************************************************************/
+
+Method(GHDS, 1)
+{
+  Store(Arg0, TIDX) // Store the table number
+  //
+  // Call GNOT for CEVT = 1 = hotkey, notify value = 0
+  //
+  Return(GNOT(1, 0)) // Return stats from GNOT
+}
+
+/************************************************************************;
+;*
+;* Name:        GLID
+;*
+;* Description: Handle a lid event (performs the Notify(GFX0, 0), but not the
+;*              lid notify).
+;*
+;* Usage:       This method must be called when a lid event occurs.  A
+;*              Notify(LID0, 0x80) must follow the call to this method.
+;*
+;* Input:       Arg0 = Lid state:
+;*                0 = All closed
+;*                1 = internal LFP lid open
+;*                2 = external lid open
+;*                3 = both external and internal open
+;*
+;* Output:      Returns 0=success, 1=failure.
+;*              CLID and CEVT are indirect outputs.
+;*
+;* References:  CLID, GNOT
+;*
+;************************************************************************/
+
+Method(GLID, 1)
+{
+
+  If (LEqual(Arg0,1))
+  {
+    Store(3,CLID)
+  }
+  Else
+  {
+    Store(Arg0, CLID)
+  }
+  //
+  //Store(Arg0, CLID) // Store the current lid state
+  // Call GNOT for CEVT=2=Lid, notify value = 0
+  //
+  if (GNOT(2, 0)) {
+    Or (CLID, 0x80000000, CLID)
+    Return (1) // Return Fail
+  }
+
+  Return (0) // Return Pass
+}
+
+/************************************************************************;
+;*
+;* Name:  GDCK
+;*
+;* Description: Handle a docking event by updating the current docking status
+;*              and doing a notification.
+;*
+;* Usage:       This method must be called when a docking event occurs.
+;*
+;* Input:       Arg0 = Docking state:
+;*                0 = Undocked
+;*                1 = Docked
+;*
+;* Output:      Returns 0=success, 1=failure.
+;*              CDCK and CEVT are indirect outputs.
+;*
+;* References:  CDCK, GNOT
+;*
+;************************************************************************/
+
+Method(GDCK, 1)
+{
+  Store(Arg0, CDCK) // Store the current dock state
+  //
+  // Call GNOT for CEVT=4=Dock, notify value = 0
+  //
+  Return(GNOT(4, 0)) // Return stats from GNOT
+}
+
+/************************************************************************;
+;* ASLE Interrupt Methods
+;************************************************************************/
+
+/************************************************************************;
+;*
+;* Name:        PARD
+;*
+;* Description: Check if the driver is ready to handle ASLE interrupts
+;*              generate by the system BIOS.
+;*
+;* Usage:       This method must be called before generating each ASLE
+;*              interrupt.
+;*
+;* Input:       None
+;*
+;* Output:      Returns 0 = success, 1 = failure.
+;*
+;* References:  ARDY (Driver readiness), ASLP (Driver recommended sleep
+;*              timeout value)
+;*
+;************************************************************************/
+
+Method(PARD)
+{
+  If(LNot(ARDY))
+  {
+    //
+    // Sleep for ASLP milliseconds if the driver is not ready.
+    //
+    Sleep(ASLP)
+  }
+  //
+  // If ARDY is clear, the driver is not ready.  If the return value is
+  // !=0, do not generate the ASLE interrupt.
+  //
+  Return(LNot(ARDY))
+}
+
+//
+// Intel Ultrabook Event Handler.  Arg0 represents the Ultrabook Event Bit # to pass
+// to the Intel Graphics Driver.  Note that this is a serialized method, meaning
+// sumultaneous events are not allowed.
+//
+Method(IUEH,1,Serialized)
+{
+  And(IUER,0xC0,IUER) // Clear all button events on entry.
+  XOr(IUER,Shiftleft(1,Arg0),IUER) // Toggle status.
+
+  If(LLessEqual(Arg0,4)) // Button Event?
+  {
+    Return(AINT(5,0)) // Generate event and return status.
+
+  }
+  Else // Indicator Event.
+  {
+    Return(AINT(Arg0,0)) // Generate event and return status.
+  }
+}
+
+/************************************************************************;
+;*
+;* Name:        AINT
+;*
+;* Description: Call the appropriate methods to generate an ASLE interrupt.
+;*              This process includes ensuring the graphics driver is ready
+;*              to process the interrupt, ensuring the driver supports the
+;*              interrupt of interest, and passing information about the event
+;*              to the graphics driver.
+;*
+;* Usage:       This method must called to generate an ASLE interrupt.
+;*
+;* Input:       Arg0 = ASLE command function code:
+;*                0 = Set ALS illuminance
+;*                1 = Set backlight brightness
+;*                2 = Do Panel Fitting
+;*                4 = Reserved
+;*                5 = Button Indicator Event
+;*                6 = Convertible Indicator Event
+;*                7 = Docking Indicator Event
+;*              Arg1 = If Arg0 = 0, current ALS reading:
+;*                0 = Reading below sensor range
+;*                1-0xFFFE = Current sensor reading
+;*                0xFFFF = Reading above sensor range
+;*              Arg1 = If Arg0 = 1, requested backlight percentage
+;*
+;* Output:      Returns 0 = success, 1 = failure
+;*
+;* References:  PARD method.
+;*
+;************************************************************************/
+
+Method(AINT, 2)
+{
+  //
+  // Return failure if the requested feature is not supported by the
+  // driver.
+  //
+  If(LNot(And(TCHE, ShiftLeft(1, Arg0))))
+  {
+    Return(0x1)
+  }
+  //
+  // Return failure if the driver is not ready to handle an ASLE
+  // interrupt.
+  //
+  If(PARD())
+  {
+    Return(0x1)
+  }
+  //
+  // Handle Intel Ultrabook Events.
+  //
+  If(LAnd(LGreaterEqual(Arg0,5),LLessEqual(Arg0,7)))
+  {
+    Store(ShiftLeft(1,Arg0), ASLC) // Set Ultrbook Event [6:4].
+    Store(0x01, ASLE) // Generate ASLE interrupt
+
+    Store(0,Local2) // Use Local2 as a timeout counter.  Intialize to zero.
+
+    While(LAnd(LLess(Local2,250),LNotEqual(ASLC,0))) // Wait 1 second or until Driver ACKs a success.
+    {
+      Sleep(4) // Delay 4 ms.
+      Increment(Local2) // Increment Timeout.
+    }
+
+    Return(0) // Return success
+  }
+  //
+  // Evaluate the first argument (Panel fitting, backlight brightness, or ALS).
+  //
+  If(LEqual(Arg0, 2))         // Arg0 = 2, so request a panel fitting mode change.
+  {
+    If(CPFM)                  // If current mode field is non-zero use it.
+    {
+      And(CPFM, 0x0F, Local0) // Create variables without reserved
+      And(EPFM, 0x0F, Local1) // or valid bits.
+
+      If(LEqual(Local0, 1))   // If current mode is centered,
+      {
+        If(And(Local1, 6))    // and if stretched is enabled,
+        {
+          Store(6, PFIT)      // request stretched.
+        }
+        Else                  // Otherwise,
+        {
+          If(And(Local1, 8))  // if aspect ratio is enabled,
+          {
+            Store(8, PFIT)    // request aspect ratio.
+          }
+          Else                // Only centered mode is enabled
+          {
+            Store(1, PFIT)    // so request centered. (No change.)
+          }
+        }
+      }
+      If(LEqual(Local0, 6))   // If current mode is stretched,
+      {
+        If(And(Local1, 8))    // and if aspect ratio is enabled,
+        {
+          Store(8, PFIT)      // request aspect ratio.
+        }
+        Else                  // Otherwise,
+        {
+          If(And(Local1, 1))  // if centered is enabled,
+          {
+            Store(1, PFIT)    // request centered.
+          }
+          Else                // Only stretched mode is enabled
+          {
+            Store(6, PFIT)    // so request stretched. (No change.)
+          }
+        }
+      }
+      If(LEqual(Local0, 8))   // If current mode is aspect ratio,
+      {
+        If(And(Local1, 1))    // and if centered is enabled,
+        {
+          Store(1, PFIT)      // request centered.
+        }
+        Else                  // Otherwise,
+        {
+          If(And(Local1, 6))  // if stretched is enabled,
+          {
+            Store(6, PFIT)    // request stretched.
+          }
+          Else                // Only aspect ratio mode is enabled
+          {
+            Store(8, PFIT)    // so request aspect ratio. (No change.)
+          }
+        }
+      }
+    }
+    //
+    // The following code for panel fitting (within the Else condition) is retained for backward compatiblity.
+    //
+    Else                      // If CFPM field is zero use PFIT and toggle the
+    {
+      Xor(PFIT,7,PFIT)        // mode setting between stretched and centered only.
+    }
+    Or(PFIT,0x80000000,PFIT)  // Set the valid bit for all cases.
+    Store(4, ASLC)            // Store "Panel fitting event" to ASLC[31:1]
+  }
+  Else
+  {
+    If(LEqual(Arg0, 1)) // Arg0=1, so set the backlight brightness.
+    {
+      Store(Divide(Multiply(Arg1, 255), 100), BCLP) // Convert from percent to 0-255.
+      Or(BCLP, 0x80000000, BCLP) // Set the valid bit.
+      Store(2, ASLC) // Store "Backlight control event" to ASLC[31:1]
+    }
+    Else
+    {
+      If(LEqual(Arg0, 0)) // Arg0=0, so set the ALS illuminace
+      {
+        Store(Arg1, ALSI)
+        Store(1, ASLC) // Store "ALS event" to ASLC[31:1]
+      }
+      Else
+      {
+        Return(0x1) // Unsupported function
+      }
+    }
+  }
+
+  Store(0x01, ASLE) // Generate ASLE interrupt
+  Return(0x0) // Return success
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxDsm.asl b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxDsm.asl
new file mode 100644
index 0000000000..ecd87e8c1f
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxDsm.asl
@@ -0,0 +1,398 @@
+/** @file
+  IGD OpRegion/_DSM Reference Code.
+  This file contains Get BIOS Data and Callback functions for
+  the Integrated Graphics Device (IGD) OpRegion/DSM mechanism
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+External(\_SB.PC00.IMMC, MethodObj)
+External(\_SB.PC00.IMMD, MethodObj)
+
+//
+// _DSM Device Specific Method
+//
+// Arg0: UUID Unique function identifier
+// Arg1: Integer Revision Level
+// Arg2: Integer Function Index (1 = Return Supported Functions)
+// Arg3: Additional Inputs/Package Parameters Bits [31:0] input as {Byte0, Byte1, Byte2, Byte3} to BIOS which is passed as 32 bit DWORD by Driver
+//
+Method (_DSM, 4, Serialized, 0, UnknownObj, {BuffObj, IntObj, IntObj, PkgObj}) {
+
+  If (LEqual(Arg0, ToUUID ("3E5B41C6-EB1D-4260-9D15-C71FBADAE414"))) {
+    //
+    // _DSM Definition for Igd functions
+    // Arguments:
+    // Arg0: UUID: 3E5B41C6-EB1D-4260-9D15-C71FBADAE414
+    // Arg1: Revision ID: 1
+    // Arg2: Function Index: 16
+    // Arg3: Additional Inputs Bits[31:0] Arg3 {Byte0, Byte1, Byte2, Byte3}
+    //
+    // Return:
+    // Success for simple notification, Opregion update for some routines and a Package for AKSV
+    //
+    If (Lor(LEqual(Arg2,18),LEqual(Arg2,19))) {
+      CreateDwordField(Arg3, 0x0, DDIN)
+      CreateDwordField(Arg3, 0x4, BUF1)
+      //
+      // OPTS is return buffer from IOM mailbox -
+      // Byte[0] is Status field.
+      // BYTE[1] is HDP Count.
+      //
+      Name(OPTS, Buffer(4){0,0,0,0})
+      CreateByteField(OPTS, 0x00, CMST) // Command Status field
+                                        //         Success - 0
+                                        //         Fail    - 1
+      CreateByteField(OPTS, 0x01, RTB1) // Return Buffer 1
+
+      //
+      // Gfx Empty Dongle Buffer is data for return DSM fun#
+      // with below buffer format
+      // Byte[0-3] is Data field.
+      // Byte[4] is Status field.
+      //
+      Name(GEDB, Buffer(5){0,0,0,0,0})
+      CreateDwordField(GEDB, 0x00, GEDF) // Gfx Empty Dongle Data Field
+      CreateByteField(GEDB, 0x04, GESF)  // Gfx Empty Dongle Status Field
+                                         //         Success - 0
+                                         //         Fail    - None 0
+    }
+
+    //
+    // Switch by function index
+    //
+    Switch(ToInteger(Arg2)) {
+      //
+      // Function Index: 0
+      // Standard query - A bitmask of functions supported
+      //
+      // Return: A bitmask of functions supported
+      //
+      Case (0)
+      {
+        If (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
+          Store("iGfx Supported Functions Bitmap ", Debug)
+
+          Return(0xDE7FF)
+        }
+      }
+
+      //
+      // Function Index: 1
+      // Adapter Power State Notification
+      // Arg3 Bits [7:0]: Adapter Power State bits [7:0] from Driver 00h = D0; 01h = D1; 02h = D2; 04h = D3 (Cold/Hot); 08h = D4 (Hibernate Notification)
+      // Return: Success
+      //
+      Case(1) {
+        If (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
+          Store(" Adapter Power State Notification ", Debug)
+
+          //
+          // Handle Low Power S0 Idle Capability if enabled
+          //
+          If(LAnd(LEqual(S0ID, 1),LLess(OSYS, 2015))) {
+            //
+            // Call GUAM to trigger CS Entry
+            //   If Adapter Power State Notification = D1 (Arg3[0]=0x01)
+            //
+            If (LEqual (And(DerefOf (Index (Arg3,0)), 0xFF), 0x01)) {
+              // GUAM - Global User Absent Mode Notification Method
+              \GUAM(One) // 0x01 - Power State Standby (CS Entry)
+            }
+            Store(And(DerefOf (Index (Arg3,1)), 0xFF), Local0)
+            //
+            // Call GUAM
+            // If Display Turn ON Notification (Arg3 [1] == 0) for CS Exit
+            //
+            If (LEqual (Local0, 0)) {
+              // GUAM - Global User Absent Mode Notification Method
+              \GUAM(0)
+            }
+          }
+
+          // Upon notification from driver that the Adapter Power State = D0,
+          // check if previous lid event failed.  If it did, retry the lid
+          // event here.
+          If(LEqual(DerefOf (Index (Arg3,0)), 0)) {
+            Store(CLID, Local0)
+            If(And(0x80000000,Local0)) {
+              And(CLID, 0x0000000F, CLID)
+              GLID(CLID)
+            }
+          }
+          Return(0x01)
+        }
+      }
+      //
+      // Function Index: 2
+      // Display Power State Notification
+      // Arg3: Display Power State Bits [15:8]
+      // 00h = On
+      // 01h = Standby
+      // 02h = Suspend
+      // 04h = Off
+      // 08h = Reduced On
+      // Return: Success
+      //
+     Case(2) {
+        if (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
+
+          Store("Display Power State Notification ", Debug)
+          Return(0x01)
+        }
+      }
+
+      //
+      // Function Index: 3
+      // BIOS POST Completion Notification
+      // Return: Success
+      //
+      Case(3) {
+        if (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
+          Store("BIOS POST Completion Notification ", Debug)
+          Return(0x01)      // Not supported, but no failure
+        }
+      }
+
+      //
+      // Function Index: 4
+      // Pre-Hires Set Mode
+      // Return: Success
+      //
+      Case(4) {
+        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+          Store("Pre-Hires Set Mode ", Debug)
+          Return(0x01)      // Not supported, but no failure
+        }
+      }
+
+      //
+      // Function Index: 5
+      // Post-Hires Set Mode
+      // Return: Success
+      //
+      Case(5) {
+        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+          Store("Post-Hires Set Mode ", Debug)
+          Return(0x01)      // Not supported, but no failure
+        }
+      }
+
+      //
+      // Function Index: 6
+      // SetDisplayDeviceNotification (Display Switch)
+      // Return: Success
+      //
+      Case(6) {
+        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+          Store("SetDisplayDeviceNotification", Debug)
+          Return(0x01)      // Not supported, but no failure
+        }
+      }
+
+      //
+      // Function Index: 7
+      // SetBootDevicePreference
+      // Return: Success
+      //
+      Case(7) {
+        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+          //<TODO> An OEM may elect to implement this method.  In that case,
+          // the input values must be saved into non-volatile storage for
+          // parsing during the next boot.  The following Sample code is Intel
+          // validated implementation.
+
+          Store("SetBootDevicePreference ", Debug)
+          And(DerefOf (Index (Arg3,0)), 0xFF, IBTT) // Save the boot display to NVS
+          Return(0x01)
+        }
+      }
+
+      //
+      // Function Index: 8
+      // SetPanelPreference
+      // Return: Success
+      //
+      Case(8) {
+        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+          // An OEM may elect to implement this method.  In that case,
+          // the input values must be saved into non-volatile storage for
+          // parsing during the next boot.  The following Sample code is Intel
+          // validated implementation.
+
+          Store("SetPanelPreference ", Debug)
+
+          // Set the panel-related NVRAM variables based the input from the driver.
+          And(DerefOf (Index (Arg3,0)), 0xFF, IPSC)
+
+          // Change panel type if a change is requested by the driver (Change if
+          // panel type input is non-zero).  Zero=No change requested.
+          If(And(DerefOf (Index (Arg3,1)), 0xFF)) {
+            And(DerefOf (Index (Arg3,1)), 0xFF, IPAT)
+            Decrement(IPAT)    // 0 = no change, so fit to CMOS map
+          }
+          And(ShiftRight(DerefOf (Index (Arg3,2)), 4), 0x7, IBIA)
+          Return(0x01)         // Success
+        }
+      }
+
+      //
+      // Function Index: 9
+      // FullScreenDOS
+      // Return: Success
+      //
+      Case(9) {
+        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+          Store("FullScreenDOS ", Debug)
+          Return(0x01)      // Not supported, but no failure
+        }
+      }
+
+      //
+      // Function Index: 10
+      // APM Complete
+      // Return: Adjusted Lid State
+      //
+     Case(10) {
+        if (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
+
+          Store("APM Complete ", Debug)
+          Store(ShiftLeft(LIDS, 8), Local0) // Report the lid state
+          Add(Local0, 0x100, Local0)        // Adjust the lid state, 0 = Unknown
+          Return(Local0)
+        }
+      }
+
+      //
+      //
+      // Function Index: 13
+      // GetBootDisplayPreference
+      // Arg3 Bits [30:16] : Boot Device Ports
+      // Arg3 Bits [7:0] : Boot Device Type
+      // Return: Boot device port and Boot device type from saved configuration
+      //
+     Case(13) {
+        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+
+          Store("GetBootDisplayPreference ", Debug)
+          Or(ShiftLeft(DerefOf (Index (Arg3,3)), 24), ShiftLeft(DerefOf (Index (Arg3,2)), 16), Local0) // Combine Arg3 Bits [31:16]
+          And(Local0, 0xEFFF0000, Local0)
+          And(Local0, ShiftLeft(DeRefOf(Index(DBTB, IBTT)), 16), Local0)
+          Or(IBTT, Local0, Local0) // Arg3 Bits [7:0] = Boot device type
+          Return(Local0)
+        }
+      }
+
+      //
+      // Function Index: 14
+      // GetPanelDetails
+      // Return: Different Panel Settings
+      //
+      Case(14) {
+        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+          Store("GetPanelDetails ", Debug)
+
+          // Report the scaling setting
+          // Bits [7:0] - Panel Scaling
+          // Bits contain the panel scaling user setting from CMOS
+          // 00h = On: Auto
+          // 01h = On: Force Scaling
+          // 02h = Off
+          // 03h = Maintain Aspect Ratio
+
+          Store(IPSC, Local0)
+          Or(Local0, ShiftLeft(IPAT, 8), Local0)
+
+          // Adjust panel type, 0 = VBT default
+          // Bits [15:8] - Panel Type
+          // Bits contain the panel type user setting from CMOS
+          // 00h = Not Valid, use default Panel Type & Timings from VBT
+          // 01h - 0Fh = Panel Number
+
+          Add(Local0, 0x100, Local0)
+
+          // Report the lid state and Adjust it
+          // Bits [16] - Lid State
+          // Bits contain the current panel lid state
+          // 0 = Lid Open
+          // 1 = Lid Closed
+
+          Or(Local0, ShiftLeft(LIDS, 16), Local0)
+          Add(Local0, 0x10000, Local0)
+
+         // Report the BIA setting
+         // Bits [22:20] - Backlight Image Adaptation (BIA) Control
+         // Bits contain the backlight image adaptation control user setting from CMOS
+         // 000 = VBT Default
+         // 001 = BIA Disabled (BLC may still be enabled)
+         // 010 - 110 = BIA Enabled at Aggressiveness Level [1 - 5]
+
+          Or(Local0, ShiftLeft(IBIA, 20), Local0)
+          Return(Local0)
+        }
+      }
+
+      //
+      // Function Index: 15
+      // GetInternalGraphics
+      // Return: Different Internal Grahics Settings
+      //
+
+      Case(15) {
+        if (LEqual(Arg1, 1)){ // test Arg1 for Revision ID: 1
+          Store("GetInternalGraphics ", Debug)
+
+          Store(GIVD, Local0)                    // Local0[0]      - VGA mode(1=VGA)
+          Xor(Local0, 1, Local0)                 // Invert the VGA mode polarity
+
+          Or(Local0, ShiftLeft(GMFN, 1), Local0) // Local0[1]      - # IGD PCI functions-1
+                                                 // Local0[3:2]    - Reserved
+                                                 // Local0[4]      - IGD D3 support(0=cold)
+                                                 // Local0[10:5]   - Reserved
+          Or(Local0, ShiftLeft(3, 11), Local0)   // Local0[12:11]  - DVMT version (11b = 5.0)
+
+          //
+          // Report DVMT 5.0 Total Graphics memory size.
+          //
+          Or(Local0, ShiftLeft(IDMS, 17), Local0) // Bits 20:17 are for Gfx total memory size
+
+          // If the "Set Internal Graphics" call is supported, the modified
+          // settings flag must be programmed per the specification.  This means
+          // that the flag must be set to indicate that system BIOS requests
+          // these settings.  Once "Set Internal Graphics" is called, the
+          //  modified settings flag must be cleared on all subsequent calls to
+          // this function.
+
+          // Report the graphics frequency based on B0:D2:F0:RF0h[12].  Must
+          // take into account the current VCO.
+
+          Or(ShiftLeft(DeRefOf(Index(DeRefOf(Index(CDCT, HVCO)), CDVL)), 21),Local0, Local0)
+          Return(Local0)
+        }
+      }
+
+      //
+      // Function Index: 16
+      // GetAKSV
+      // Retrun: 5 bytes of AKSV
+      //
+      Case(16) {
+        if (LEqual(Arg1, 1)) { // test Arg1 for Revision ID: 1
+
+          Store("GetAKSV ", Debug)
+          Name (KSVP, Package()
+          {
+             0x80000000,
+             0x8000
+          })
+          Store(KSV0, Index(KSVP,0)) // First four bytes of AKSV
+          Store(KSV1, Index(KSVP,1)) // Fifth byte of AKSV
+          Return(KSVP) // Success
+        }
+      }
+    } // End of switch(Arg2)
+  } // End of if (ToUUID("3E5B41C6-EB1D-4260-9D15-C71FBADAE414D"))
+
+  Return (Buffer () {0x00})
+} // End of _DSM
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxOpGbda.asl b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxOpGbda.asl
new file mode 100644
index 0000000000..2b5f2393b0
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxOpGbda.asl
@@ -0,0 +1,127 @@
+/** @file
+  IGD OpRegion/Software SCI Reference Code.
+  This file contains Get BIOS Data Area funciton support for
+  the Integrated Graphics Device (IGD) OpRegion/Software SCI mechanism
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+Method (GBDA, 0, Serialized)
+{
+  //
+  // Supported calls: Sub-function 0
+  //
+  If (LEqual(GESF, 0))
+  {
+    //
+    //<NOTE> Reference code is set to Intel's validated implementation.
+    //
+    Store(0x0000659, PARM)
+    Store(Zero, GESF) // Clear the exit parameter
+    Return(SUCC) // Success
+  }
+  //
+  // Requested callbacks: Sub-function 1
+  //
+  If (LEqual(GESF, 1))
+  {
+    //
+    //<NOTE> Call back functions are where the driver calls the
+    // system BIOS at function indicated event.
+    //
+    Store(0x300482, PARM)
+    If(LEqual(S0ID, One)){
+      Or(PARM, 0x100, PARM) //Request Fn 8 callback in CS systems
+    }
+    Store(Zero, GESF) // Clear the exit parameter
+    Return(SUCC) // Success
+  }
+  //
+  // Get Boot display Preferences: Sub-function 4
+  //
+  If (LEqual(GESF, 4))
+  {
+    //
+    //<NOTE> Get Boot Display Preferences function.
+    //
+    And(PARM, 0xEFFF0000, PARM) // PARM[30:16] = Boot device ports
+    And(PARM, ShiftLeft(DeRefOf(Index(DBTB, IBTT)), 16), PARM)
+    Or(IBTT, PARM, PARM) // PARM[7:0] = Boot device type
+    Store(Zero, GESF) // Clear the exit parameter
+    Return(SUCC) // Success
+  }
+  //
+  // Panel details: Sub-function 5
+  //
+  If (LEqual(GESF, 5))
+  {
+    //
+    //<NOTE> Get Panel Details function.
+    //
+    Store(IPSC, PARM) // Report the scaling setting
+    Or(PARM, ShiftLeft(IPAT, 8), PARM)
+    Add(PARM, 0x100, PARM) // Adjust panel type, 0 = VBT default
+    Or(PARM, ShiftLeft(LIDS, 16), PARM) // Report the lid state
+    Add(PARM, 0x10000, PARM) // Adjust the lid state, 0 = Unknown
+    Or(PARM, ShiftLeft(IBIA, 20), PARM) // Report the BIA setting
+    Store(Zero, GESF)
+    Return(SUCC)
+  }
+  //
+  // Internal graphics: Sub-function 7
+  //
+  If (LEqual(GESF, 7))
+  {
+    Store(GIVD, PARM) // PARM[0]      - VGA mode(1=VGA)
+    Xor(PARM, 1, PARM) // Invert the VGA mode polarity
+    Or(PARM, ShiftLeft(GMFN, 1), PARM) // PARM[1]   - # IGD PCI functions-1
+                                       // PARM[3:2]    - Reserved
+                                       // PARM[4]      - IGD D3 support(0=cold)
+                                       // PARM[10:5]   - Reserved
+    Or(PARM, ShiftLeft(3, 11), PARM) // PARM[12:11] - DVMT mode(11b = 5.0)
+
+    //
+    // Report DVMT 5.0 Total Graphics memory size.
+    //
+    Or(PARM, ShiftLeft(IDMS, 17), PARM) // Bits 20:17 are for Gfx total memory size
+    //
+    // If the "Set Internal Graphics" call is supported, the modified
+    // settings flag must be programmed per the specification.  This means
+    // that the flag must be set to indicate that system BIOS requests
+    // these settings.  Once "Set Internal Graphics" is called, the
+    //  modified settings flag must be cleared on all subsequent calls to
+    // this function.
+    // Report the graphics frequency based on B0:D2:F0:RF0h[12].  Must
+    // take into account the current VCO.
+    //
+    Or(ShiftLeft(Derefof(Index(Derefof(Index(CDCT, HVCO)), CDVL)), 21),PARM, PARM)
+    Store(1, GESF) // Set the modified settings flag
+    Return(SUCC)
+  }
+  //
+  // Spread spectrum clocks: Sub-function 10
+  //
+  If (LEqual(GESF, 10))
+  {
+    Store(0, PARM) // Assume SSC is disabled
+    If(ISSC)
+    {
+      Or(PARM, 3, PARM) // If SSC enabled, return SSC1+Enabled
+    }
+    Store(0, GESF) // Set the modified settings flag
+    Return(SUCC) // Success
+  }
+
+  If (LEqual(GESF, 11))
+  {
+    Store(KSV0, PARM) // First four bytes of AKSV
+    Store(KSV1, GESF) // Fifth byte of AKSV
+
+    Return(SUCC) // Success
+  }
+  //
+  // A call to a reserved "Get BIOS data" function was received.
+  //
+  Store(Zero, GESF) // Clear the exit parameter
+  Return(CRIT) // Reserved, "Critical failure"
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxOpRn.asl b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxOpRn.asl
new file mode 100644
index 0000000000..410524b324
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxOpRn.asl
@@ -0,0 +1,314 @@
+/** @file
+  IGD OpRegion/Software SCI Reference Code.
+  This file contains the interrupt handler code for the Integrated
+  Graphics Device (IGD) OpRegion/Software SCI mechanism.
+  It defines OperationRegions to cover the IGD PCI configuration space
+  as described in the IGD OpRegion specification.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+//
+//NOTES:
+//
+// (1) The code contained in this file inherits the scope in which it
+//     was included.  So BIOS developers must be sure to include this
+//     file in the scope associated with the graphics device
+//     (ex. \_SB.PC00.GFX0).
+// (2) Create a _L06 method under the GPE scope to handle the event
+//     generated by the graphics driver.  The _L06 method must call
+//     the GSCI method in this file.
+// (3) The MCHP operation region assumes that _ADR and _BBN names
+//     corresponding to bus 0, device0, function 0 have been declared
+//     under the PC00 scope.
+// (4) Before the first execution of the GSCI method, the base address
+//     of the GMCH SCI OpRegion must be programmed where the driver can
+//     access it. A 32bit scratch register at 0xFC in the IGD PCI
+//     configuration space (B0/D2/F0/R0FCh) is used for this purpose.
+
+//  Define an OperationRegion to cover the GMCH PCI configuration space as
+//  described in the IGD OpRegion specificiation.
+//
+Scope(\_SB.PC00)
+{
+  OperationRegion(MCHP, PCI_Config, 0x40, 0xC0)
+  Field(MCHP, AnyAcc, NoLock, Preserve)
+  {
+    Offset(0x14),
+    AUDE, 8,
+
+    Offset(0x60), // Top of Memory register
+    TASM, 10,     // Total system memory (64MB gran)
+        , 6,
+  }
+}
+
+//
+//  Define an OperationRegion to cover the IGD PCI configuration space as
+//  described in the IGD OpRegion specificiation.
+//
+OperationRegion(IGDP, PCI_Config, 0x40, 0xC0)
+Field(IGDP, AnyAcc, NoLock, Preserve)
+{
+  Offset(0x10), // Mirror of gfx control reg
+      , 1,
+  GIVD, 1,      // IGD VGA disable bit
+      , 2,
+  GUMA, 3,      // Stolen memory size
+      , 9,
+  Offset(0x14),
+      , 4,
+  GMFN, 1,      // Gfx function 1 enable
+      , 27,
+  Offset(0xA4),
+  ASLE, 8,      // Reg 0xE4, ASLE interrupt register
+      , 24,     // Only use first byte of ASLE reg
+  Offset(0xA8), // Reg 0xE8, SWSCI control register
+  GSSE, 1,      // Graphics SCI event (1=event pending)
+  GSSB, 14,     // Graphics SCI scratchpad bits
+  GSES, 1,      // Graphics event select (1=SCI)
+  Offset(0xB0), // Gfx Clk Frequency and Gating Control
+      , 12,
+  CDVL, 1,      // Core display clock value
+      , 3,      // Graphics Core Display Clock Select
+  Offset(0xB5),
+  LBPC, 8,      // Legacy brightness control
+  Offset(0xBC),
+  ASLS, 32,     // Reg 0xFC, Address of the IGD OpRegion
+}
+
+//
+//  Define an OperationRegion to cover the IGD OpRegion layout.
+//
+OperationRegion(IGDM, SystemMemory, ASLB, 0x2000)
+Field(IGDM, AnyAcc, NoLock, Preserve)
+{
+  //
+  // OpRegion Header
+  //
+  SIGN, 128,     // Signature-"IntelGraphicsMem"
+  SIZE, 32,      // OpRegion Size
+  OVER, 32,      // OpRegion Version
+  SVER, 256,     // System BIOS Version
+  VVER, 128,     // VBIOS Version
+  GVER, 128,     // Driver version
+  MBOX, 32,      // Mailboxes supported
+  DMOD, 32,      // Driver Model
+  PCON, 32,      // Platform Configuration
+  DVER, 64,      // GOP Version
+  //
+  // OpRegion Mailbox 1 (Public ACPI Methods)
+  // Note: Mailbox 1 is normally reserved for desktop platforms.
+  //
+  Offset(0x100),
+  DRDY, 32,      // Driver readiness (ACPI notification)
+  CSTS, 32,      // Notification status
+  CEVT, 32,      // Current event
+  Offset(0x120),
+  DIDL, 32,      // Supported display device ID list
+  DDL2, 32,      // Allows for 8 devices
+  DDL3, 32,
+  DDL4, 32,
+  DDL5, 32,
+  DDL6, 32,
+  DDL7, 32,
+  DDL8, 32,
+  CPDL, 32,      // Currently present display list
+  CPL2, 32,      // Allows for 8 devices
+  CPL3, 32,
+  CPL4, 32,
+  CPL5, 32,
+  CPL6, 32,
+  CPL7, 32,
+  CPL8, 32,
+  CADL, 32,      // Currently active display list
+  CAL2, 32,      // Allows for 8 devices
+  CAL3, 32,
+  CAL4, 32,
+  CAL5, 32,
+  CAL6, 32,
+  CAL7, 32,
+  CAL8, 32,
+  NADL, 32,      // Next active display list
+  NDL2, 32,      // Allows for 8 devices
+  NDL3, 32,
+  NDL4, 32,
+  NDL5, 32,
+  NDL6, 32,
+  NDL7, 32,
+  NDL8, 32,
+  ASLP, 32,      // ASL sleep timeout
+  TIDX, 32,      // Toggle table index
+  CHPD, 32,      // Current hot plug enable indicator
+  CLID, 32,      // Current lid state indicator
+  CDCK, 32,      // Current docking state indicator
+  SXSW, 32,      // Display switch notify on resume
+  EVTS, 32,      // Events supported by ASL (diag only)
+  CNOT, 32,      // Current OS notifications (diag only)
+  NRDY, 32,
+  //
+  //Extended DIDL list
+  //
+  DDL9, 32,
+  DD10, 32,
+  DD11, 32,
+  DD12, 32,
+  DD13, 32,
+  DD14, 32,
+  DD15, 32,
+  //
+  //Extended Currently attached Display Device List  CPD2
+  //
+  CPL9, 32,
+  CP10, 32,
+  CP11, 32,
+  CP12, 32,
+  CP13, 32,
+  CP14, 32,
+  CP15, 32,
+  //
+  // OpRegion Mailbox 2 (Software SCI Interface)
+  //
+  Offset(0x200), // SCIC
+  SCIE, 1,       // SCI entry bit (1=call unserviced)
+  GEFC, 4,       // Entry function code
+  GXFC, 3,       // Exit result
+  GESF, 8,       // Entry/exit sub-function/parameter
+      , 16,      // SCIC[31:16] reserved
+  Offset(0x204), // PARM
+  PARM, 32,      // PARM register (extra parameters)
+  DSLP,  32,     // Driver sleep time out
+  //
+  // OpRegion Mailbox 3 (BIOS to Driver Notification)
+  // Note: Mailbox 3 is normally reserved for desktop platforms.
+  //
+  Offset(0x300),
+  ARDY, 32,      // Driver readiness (power conservation)
+  ASLC, 32,      // ASLE interrupt command/status
+  TCHE, 32,      // Technology enabled indicator
+  ALSI, 32,      // Current ALS illuminance reading
+  BCLP, 32,      // Backlight brightness
+  PFIT, 32,      // Panel fitting state or request
+  CBLV, 32,      // Current brightness level
+  BCLM, 320,     // Backlight brightness level duty cycle mapping table
+  CPFM, 32,      // Current panel fitting mode
+  EPFM, 32,      // Enabled panel fitting modes
+  PLUT, 592,     // Optional. 74-byte Panel LUT Table
+  PFMB, 32,      // Optional. PWM Frequency and Minimum Brightness
+  CCDV, 32,      // Optional. Gamma, Brightness, Contrast values.
+  PCFT, 32,      // Optional. Power Conservation Features
+  SROT, 32,      // Supported rotation angle.
+  IUER, 32,      // Optional. Intel Ultrabook Event Register.
+  FDSS, 64,      // Optional. FFS Display Physical address
+  FDSP, 32,      // Optional. FFS Display Size
+  STAT, 32,      // State Indicator
+  RVDA, 64,      // Physical address of Raw VBT data
+  RVDS, 32,      // Size of Raw VBT data
+  //
+  // OpRegion Mailbox 4 (VBT)
+  //
+  Offset(0x400),
+  RVBT, 0xC000,  // 6K bytes maximum VBT image
+  //
+  // OpRegion Mailbox 5 (BIOS to Driver Notification Extension)
+  //
+  Offset(0x1C00),
+  PHED, 32,      // Panel Header
+  BDDC, 2048,    // Panel EDID (Max 256 bytes)
+
+}
+
+//
+// Convert boot display type into a port mask.
+//
+Name (DBTB, Package()
+{
+  0x0000,        // Automatic
+  0x0007,        // Port-0 : Integrated CRT
+  0x0038,        // Port-1 : DVO-A, or Integrated LVDS
+  0x01C0,        // Port-2 : SDVO-B, or SDVO-B/C
+  0x0E00,        // Port-3 : SDVO-C
+  0x003F,        // [CRT + DVO-A / Integrated LVDS]
+  0x01C7,        // [CRT + SDVO-B] or [CRT + SDVO-B/C]
+  0x0E07,        // [CRT + SDVO-C]
+  0x01F8,        // [DVO-A / Integrated LVDS + SDVO-B]
+  0x0E38,        // [DVO-A / Integrated LVDS + SDVO-C]
+  0x0FC0,        // [SDVO-B + SDVO-C]
+  0x0000,        // Reserved
+  0x0000,        // Reserved
+  0x0000,        // Reserved
+  0x0000,        // Reserved
+  0x0000,        // Reserved
+  0x7000,        // Port-4: Integrated TV
+  0x7007,        // [Integrated TV + CRT]
+  0x7038,        // [Integrated TV + LVDS]
+  0x71C0,        // [Integrated TV + DVOB]
+  0x7E00         // [Integrated TV + DVOC]
+})
+
+//
+// Core display clock value table.
+//
+Name (CDCT, Package()
+{
+  Package() {228, 320},
+  Package() {222, 333},
+  Package() {222, 333},
+  Package() {  0,   0},
+  Package() {222, 333},
+})
+
+//
+// Defined exit result values:
+//
+Name (SUCC, 1)   // Exit result: Success
+Name (NVLD, 2)   // Exit result: Invalid parameter
+Name (CRIT, 4)   // Exit result: Critical failure
+Name (NCRT, 6)   // Exit result: Non-critical failure
+
+/************************************************************************;
+;*
+;* Name: GSCI
+;*
+;* Description: Handles an SCI generated by the graphics driver.  The
+;*              PARM and SCIC input fields are parsed to determine the
+;*              functionality requested by the driver.  GBDA or SBCB
+;*              is called based on the input data in SCIC.
+;*
+;* Usage:       The method must be called in response to a GPE 06 event
+;*              which will be generated by the graphics driver.
+;*              Ex: Method(\_GPE._L06) {Return(\_SB.PC00.GFX0.GSCI())}
+;*
+;* Input:       PARM and SCIC are indirect inputs
+;*
+;* Output:      PARM and SIC are indirect outputs
+;*
+;* References:  GBDA (Get BIOS Data method), SBCB (System BIOS Callback
+;*              method)
+;*
+;************************************************************************/
+
+Method (GSCI, 0, Serialized)
+{
+  Include("IgfxOpGbda.asl")  // "Get BIOS Data" Functions
+  Include("IgfxOpSbcb.asl")  // "System BIOS CallBacks"
+
+  If (LEqual(GEFC, 4))
+  {
+    Store(GBDA(), GXFC)    // Process Get BIOS Data functions
+  }
+
+  If (LEqual(GEFC, 6))
+  {
+    Store(SBCB(), GXFC)    // Process BIOS Callback functions
+  }
+
+  Store(0, GEFC)           // Wipe out the entry function code
+  Store(1, CPSC)           // Clear CPUSCI_STS to clear the PCH TCO SCI status
+  Store(0, GSSE)           // Clear the SCI generation bit in PCI space.
+  Store(0, SCIE)           // Clr SCI serviced bit to signal completion
+
+  Return(Zero)
+}
+
+Include("IgfxCommon.asl")    // IGD SCI mobile features
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxOpSbcb.asl b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxOpSbcb.asl
new file mode 100644
index 0000000000..3c5d4d9862
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxOpSbcb.asl
@@ -0,0 +1,261 @@
+/** @file
+  This file contains the system BIOS call back functionality for the
+  OpRegion/Software SCI mechanism.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+Method (SBCB, 0, Serialized)
+{
+  //
+  // Supported Callbacks: Sub-function 0
+  //
+  If (LEqual(GESF, 0x0))
+  {
+    //
+    //<NOTE> An OEM may support the driver->SBIOS status callbacks, but
+    // the supported callbacks value must be modified.  The code that is
+    // executed upon reception of the callbacks must be also be updated
+    // to perform the desired functionality.
+    //
+    Store(0x00000000, PARM)   // No callbacks supported
+    //Store(0x000787FD, PARM) // Used for Intel test implementaion
+    Store(0x000F87DD, PARM)
+    Store(Zero, GESF)         // Clear the exit parameter
+    Return(SUCC)              // "Success"
+  }
+  //
+  // BIOS POST Completion: Sub-function 1
+  //
+  If (LEqual(GESF, 1))
+  {
+    Store(Zero, GESF) // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)      // Not supported, but no failure
+  }
+  //
+  // Pre-Hires Set Mode: Sub-function 3
+  //
+  If (LEqual(GESF, 3))
+  {
+    Store(Zero, GESF) // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)      // Not supported, but no failure
+  }
+  //
+  // Post-Hires Set Mode: Sub-function 4
+  //
+  If (LEqual(GESF, 4))
+  {
+    Store(Zero, GESF) // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)      // Not supported, but no failure
+  }
+  //
+  // Display Switch: Sub-function 5
+  //
+  If (LEqual(GESF, 5))
+  {
+    Store(Zero, GESF) // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)      // Not supported, but no failure
+  }
+  //
+  // Adapter Power State: Sub-function 7
+  //
+  If (LEqual(GESF, 7))
+  {
+    //
+    // Handle Low Power S0 Idle Capability if enabled
+    //
+    If(LAnd(LEqual(S0ID, 1),LLess(OSYS, 2015))) {
+      //
+      // Call GUAM to trigger CS Entry
+      //   If Adapter Power State Notification = D1 (PARM[7:0]=0x01)
+      //
+      If (LEqual (And(PARM,0xFF), 0x01)) {
+        // GUAM - Global User Absent Mode Notification Method
+        \GUAM(One) // 0x01 - Power State Standby (CS Entry)
+      }
+      If (LEqual (And(PARM,0xFF), 0x00)) {
+        // GUAM - Global User Absent Mode Notification Method
+        \GUAM(0)
+      }
+    }
+    //
+    // Upon notification from driver that the Adapter Power State = D0,
+    // check if previous lid event failed.  If it did, retry the lid
+    // event here.
+    //
+    If(LEqual(PARM, 0))
+    {
+      Store(CLID, Local0)
+      If(And(0x80000000,Local0))
+      {
+        And(CLID, 0x0000000F, CLID)
+        GLID(CLID)
+      }
+    }
+    Store(Zero, GESF) // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)      // Not supported, but no failure
+  }
+  //
+  // Display Power State: Sub-function 8
+  //
+  If (LEqual(GESF, 8))
+  {
+    Store(Zero, GESF) // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)      // Not supported, but no failure
+  }
+  //
+  // Set Boot Display: Sub-function 9
+  //
+  If (LEqual(GESF, 9))
+  {
+    //
+    //<NOTE> An OEM may elect to implement this method.  In that case,
+    // the input values must be saved into non-volatile storage for
+    // parsing during the next boot.  The following Sample code is Intel
+    // validated implementation.
+    //
+    And(PARM, 0xFF, IBTT) // Save the boot display to NVS
+    Store(Zero, GESF)     // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)          // Reserved, "Critical failure"
+  }
+  //
+  // Set Panel Details: Sub-function 10 (0Ah)
+  //
+  If (LEqual(GESF, 10))
+  {
+    //
+    //<NOTE> An OEM may elect to implement this method.  In that case,
+    // the input values must be saved into non-volatile storage for
+    // parsing during the next boot.  The following Sample code is Intel
+    // validated implementation.
+    // Set the panel-related NVRAM variables based the input from the driver.
+    //
+    And(PARM, 0xFF, IPSC)
+    //
+    // Change panel type if a change is requested by the driver (Change if
+    // panel type input is non-zero).  Zero=No change requested.
+    //
+    If(And(ShiftRight(PARM, 8), 0xFF))
+    {
+      And(ShiftRight(PARM, 8), 0xFF, IPAT)
+      Decrement(IPAT)    // 0 = no change, so fit to CMOS map
+    }
+    And(ShiftRight(PARM, 20), 0x7, IBIA)
+    Store(Zero, GESF)    // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)         // Success
+  }
+  //
+  // Set Internal Graphics: Sub-function 11 (0Bh)
+  //
+  If (LEqual(GESF, 11))
+  {
+    //
+    //<NOTE> An OEM may elect to implement this method.  In that case,
+    // the input values must be saved into non-volatile storage for
+    // parsing during the next boot.  The following Sample code is Intel
+    // validated implementation.
+    //
+    And(ShiftRight(PARM, 1), 1, IF1E)      // Program the function 1 option
+    If(And(PARM, ShiftLeft(0xF, 13)))      // Use fixed memory if fixed size != 0
+    {
+      //
+      // Fixed memory
+      //
+      And(ShiftRight(PARM, 13), 0xF, IDMS) // Program fixed memory size
+    }
+    Else
+    {
+      //
+      // DVMT memory
+      //
+      And(ShiftRight(PARM, 17), 0xF, IDMS) // Program fixed memory size
+    }
+    Store(Zero, GESF)                      // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)                           // Success
+  }
+  //
+  // Post-Hires to DOS FS: Sub-function 16 (10h)
+  //
+  If (LEqual(GESF, 16))
+  {
+    Store(Zero, GESF) // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)      // Not supported, but no failure
+  }
+  //
+  // APM Complete:  Sub-function 17 (11h)
+  //
+  If (LEqual(GESF, 17))
+  {
+    Store(ShiftLeft(LIDS, 8), PARM) // Report the lid state
+    Add(PARM, 0x100, PARM)          // Adjust the lid state, 0 = Unknown
+    Store(Zero, GESF)               // Clear the exit parameter
+    Return(SUCC)                    // Not supported, but no failure
+  }
+  //
+  // Set Spread Spectrum Clocks: Sub-function 18 (12h)
+  //
+  If (LEqual(GESF, 18))
+  {
+    //
+    //<NOTE> An OEM may elect to implement this method.  In that case,
+    // the input values must be saved into non-volatile storage for
+    // parsing during the next boot.  The following Sample code is Intel
+    // validated implementation.
+    //
+    If(And(PARM, 1))
+    {
+      If(LEqual(ShiftRight(PARM, 1), 1))
+      {
+        Store(1, ISSC)  // Enable HW SSC, only for clock 1
+      }
+      Else
+      {
+        Store(Zero, GESF)
+        Return(CRIT)    // Failure, as the SSC clock must be 1
+      }
+    }
+    Else
+    {
+      Store(0, ISSC)    // Disable SSC
+    }
+    Store(Zero, GESF)   // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)        // Success
+  }
+  //
+  // Post VBE/PM Callback: Sub-function 19 (13h)
+  //
+  If (LEqual(GESF, 19))
+  {
+    Store(Zero, GESF)  // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)       // Not supported, but no failure
+  }
+  //
+  // Set PAVP Data: Sub-function 20 (14h)
+  //
+  If (LEqual(GESF, 20))
+  {
+    And(PARM, 0xF, PAVP) // Store PAVP info
+    Store(Zero, GESF)    // Clear the exit parameter
+    Store(Zero, PARM)
+    Return(SUCC)         // Success
+  }
+
+  //
+  // A call to a reserved "System BIOS callbacks" function was received
+  //
+  Store(Zero, GESF) // Clear the exit parameter
+  Return(SUCC)      // Reserved, "Critical failure"
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxSsdt.asl b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxSsdt.asl
new file mode 100644
index 0000000000..99130a853d
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxSsdt.asl
@@ -0,0 +1,73 @@
+/** @file
+  This file contains the Intel Graphics SSDT Table ASL code.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+DefinitionBlock (
+  "IgfxSsdt.aml",
+  "SSDT",
+  2,
+  "INTEL ",
+  "IgfxSsdt",
+  0x3000
+  )
+{
+  External(\_SB.PC00, DeviceObj)
+  External(\_SB.PC00.GFX0, DeviceObj)
+  External(\NDID)
+  External(\DID1)
+  External(\DID2)
+  External(\DID3)
+  External(\DID4)
+  External(\DID5)
+  External(\DID6)
+  External(\DID7)
+  External(\DID8)
+  External(\DID9)
+  External(\DIDA)
+  External(\DIDB)
+  External(\DIDC)
+  External(\DIDD)
+  External(\DIDE)
+  External(\DIDF)
+  External(\DIDX)
+  External(\DIDY)
+
+  External(\NXD1)
+  External(\NXD2)
+  External(\NXD3)
+  External(\NXD4)
+  External(\NXD5)
+  External(\NXD6)
+  External(\NXD7)
+  External(\NXD8)
+  External(\NXDY)
+
+  External(\IPTP)
+  External(\EDPV)
+  External(\NXDX)
+  External(\HGMD)
+  External(\LIDS)
+  External(\BRTL)
+  External(\NSTE)
+  External(\CSTE)
+  External(\ASLB)
+  External(\IBTT)
+  External(\IPSC)
+  External(\IPAT)
+  External(\IBIA)
+  External(\IDMS)
+  External(\HVCO)
+  External(\ISSC)
+  External(\KSV0)
+  External(\KSV1)
+  External(\IF1E)
+  External(\PAVP)
+
+  Scope (\_SB.PC00.GFX0)
+  {
+    include("Igfx.asl")
+  }
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxSsdt.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxSsdt.inf
new file mode 100644
index 0000000000..be28157cef
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/AcpiTables/IgfxSsdt.inf
@@ -0,0 +1,23 @@
+## @file
+#  Component description file for the Igfx ACPI tables
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION          = 0x00010005
+BASE_NAME            = IgfxSsdt
+FILE_GUID            = CE9CAA0E-8248-442C-9E57-50F212E2BAED
+MODULE_TYPE          = USER_DEFINED
+VERSION_STRING       = 1.0
+
+[Sources]
+  IgfxSsdt.asl
+
+[Packages]
+  MdePkg/MdePkg.dec
+  TigerlakeSiliconPkg/SiPkg.dec
+
+[FixedPcd]
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/IncludePrivate/Library/DxeGraphicsInitLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/IncludePrivate/Library/DxeGraphicsInitLib.h
new file mode 100644
index 0000000000..0e9f119763
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/IncludePrivate/Library/DxeGraphicsInitLib.h
@@ -0,0 +1,53 @@
+/** @file
+  Header file for DXE Graphics Init Lib.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _DXE_GRAPHICS_INIT_LIB_H_
+#define _DXE_GRAPHICS_INIT_LIB_H_
+
+#include <Uefi.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/IoLib.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/Pci.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Protocol/SaPolicy.h>
+#include <Protocol/SaNvsArea.h>
+#include <Protocol/GopComponentName2.h>
+#include <SiConfigHob.h>
+#include <Register/SaRegsHostBridge.h>
+
+/**
+  Initialize GT ACPI tables
+
+  @param[in] ImageHandle - Handle for the image of this driver
+  @param[in] SaPolicy    - SA DXE Policy protocol
+
+  @retval EFI_SUCCESS          - GT ACPI initialization complete
+  @retval EFI_NOT_FOUND        - Dxe System Table not found.
+  @retval EFI_OUT_OF_RESOURCES - Mmio not allocated successfully.
+**/
+EFI_STATUS
+GraphicsInit (
+  IN EFI_HANDLE             ImageHandle,
+  IN SA_POLICY_PROTOCOL     *SaPolicy
+  );
+
+/**
+  Do Post GT PM Init Steps after VBIOS Initialization.
+
+  @retval EFI_SUCCESS          Succeed.
+**/
+EFI_STATUS
+PostPmInitEndOfDxe (
+  VOID
+  );
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/IncludePrivate/Library/DxeGraphicsPolicyLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/IncludePrivate/Library/DxeGraphicsPolicyLib.h
new file mode 100644
index 0000000000..abb5dffc45
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/IncludePrivate/Library/DxeGraphicsPolicyLib.h
@@ -0,0 +1,71 @@
+/** @file
+  Header file for the DXE Graphics Policy Init library.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _DXE_GRAPHICS_POLICY_LIB_H_
+#define _DXE_GRAPHICS_POLICY_LIB_H_
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Protocol/SaPolicy.h>
+#include <ConfigBlock.h>
+#include <GraphicsConfig.h>
+#include <Library/SiConfigBlockLib.h>
+
+#define WORD_FIELD_VALID_BIT  BIT15
+
+extern EFI_GUID gGraphicsDxeConfigGuid;
+
+/**
+  This function prints the Graphics DXE phase policy.
+
+  @param[in] SaPolicy - SA DXE Policy protocol
+**/
+VOID
+GraphicsDxePolicyPrint (
+  IN  SA_POLICY_PROTOCOL      *SaPolicy
+  );
+
+/**
+  This function Load default Graphics DXE policy.
+
+  @param[in] ConfigBlockPointer    The pointer to add Graphics config block
+**/
+VOID
+LoadIgdDxeDefault (
+  IN VOID    *ConfigBlockPointer
+  );
+
+
+/**
+  Get DXE Graphics config block table total size.
+
+  @retval     Size of DXE Graphics config block table
+**/
+UINT16
+EFIAPI
+GraphicsGetConfigBlockTotalSizeDxe (
+  VOID
+  );
+
+/**
+  GraphicsAddConfigBlocksDxe add all DXE Graphics config block.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add SA config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+GraphicsAddConfigBlocksDxe (
+  IN VOID           *ConfigBlockTableAddress
+  );
+
+#endif // _DXE_GRAPHICs_POLICY_LIBRARY_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/IncludePrivate/Library/DxeIgdOpRegionInitLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/IncludePrivate/Library/DxeIgdOpRegionInitLib.h
new file mode 100644
index 0000000000..683893f940
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/IncludePrivate/Library/DxeIgdOpRegionInitLib.h
@@ -0,0 +1,177 @@
+/** @file
+  This is part of the implementation of an Intel Graphics drivers OpRegion /
+  Software SCI interface between system BIOS, ASL code, and Graphics drivers.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _DXE_IGD_OPREGION_INIT_LIB_H_
+#define _DXE_IGD_OPREGION_INIT_LIB_H_
+
+///
+/// Statements that include other header files.
+///
+#include <Uefi.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <IndustryStandard/Pci.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Register/IgdRegs.h>
+#include <SiConfigHob.h>
+#include <Register/SaRegsHostBridge.h>
+///
+/// Driver Consumed Protocol Prototypes
+///
+#include <Protocol/PciIo.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/SaPolicy.h>
+#include <Protocol/SaNvsArea.h>
+///
+/// Driver Produced Protocol Prototypes
+///
+#include <Protocol/IgdOpRegion.h>
+
+#pragma pack(push, 1)
+///
+///
+/// OpRegion (Miscellaneous) defines.
+///
+/// OpRegion Header defines.
+///
+typedef UINT16  STRING_REF;
+#define HEADER_SIGNATURE            "IntelGraphicsMem"
+#define HEADER_SIZE                 0x2000
+#define HEADER_OPREGION_REV         0x00
+#define HEADER_MBOX_SUPPORT         (HD_MBOX5 + HD_MBOX4 + HD_MBOX3 + HD_MBOX2 + HD_MBOX1)
+#define HD_MBOX1                    BIT0
+#define HD_MBOX2                    BIT1
+#define HD_MBOX3                    BIT2
+#define HD_MBOX4                    BIT3
+#define HD_MBOX5                    BIT4
+#define SVER_SIZE                   32
+
+///
+/// OpRegion Mailbox 1 EQUates.
+///
+/// OpRegion Mailbox 3 EQUates.
+///
+#define ALS_ENABLE            BIT0
+#define BACKLIGHT_BRIGHTNESS  0xFF
+#define FIELD_VALID_BIT       BIT31
+#define PFIT_ENABLE           BIT2
+#define PFIT_OPRN_AUTO        0x00000000
+#define PFIT_OPRN_SCALING     0x00000007
+#define PFIT_OPRN_OFF         0x00000000
+#define PFIT_SETUP_AUTO       0
+#define PFIT_SETUP_SCALING    1
+#define PFIT_SETUP_OFF        2
+#define INIT_BRIGHT_LEVEL     0x64
+#define PFIT_STRETCH          6
+
+///
+/// Video BIOS / VBT defines
+///
+#define OPTION_ROM_SIGNATURE    0xAA55
+#define VBIOS_LOCATION_PRIMARY  0xC0000
+
+#define VBT_SIGNATURE           SIGNATURE_32 ('$', 'V', 'B', 'T')
+///
+/// Typedef stuctures
+///
+typedef struct {
+  UINT16  Signature;  /// 0xAA55
+  UINT8   Size512;
+  UINT8   Reserved[21];
+  UINT16  PcirOffset;
+  UINT16  VbtOffset;
+} INTEL_VBIOS_OPTION_ROM_HEADER;
+
+typedef struct {
+  UINT32  Signature;  /// "PCIR"
+  UINT16  VendorId;   /// 0x8086
+  UINT16  DeviceId;
+  UINT16  Reserved0;
+  UINT16  Length;
+  UINT8   Revision;
+  UINT8   ClassCode[3];
+  UINT16  ImageLength;
+  UINT16  CodeRevision;
+  UINT8   CodeType;
+  UINT8   Indicator;
+  UINT16  Reserved1;
+} INTEL_VBIOS_PCIR_STRUCTURE;
+
+typedef struct {
+  UINT8   HeaderSignature[20];
+  UINT16  HeaderVersion;
+  UINT16  HeaderSize;
+  UINT16  HeaderVbtSize;
+  UINT8   HeaderVbtCheckSum;
+  UINT8   HeaderReserved;
+  UINT32  HeaderOffsetVbtDataBlock;
+  UINT32  HeaderOffsetAim1;
+  UINT32  HeaderOffsetAim2;
+  UINT32  HeaderOffsetAim3;
+  UINT32  HeaderOffsetAim4;
+  UINT8   DataHeaderSignature[16];
+  UINT16  DataHeaderVersion;
+  UINT16  DataHeaderSize;
+  UINT16  DataHeaderDataBlockSize;
+  UINT8   CoreBlockId;
+  UINT16  CoreBlockSize;
+  UINT16  CoreBlockBiosSize;
+  UINT8   CoreBlockBiosType;
+  UINT8   CoreBlockReleaseStatus;
+  UINT8   CoreBlockHWSupported;
+  UINT8   CoreBlockIntegratedHW;
+  UINT8   CoreBlockBiosBuild[4];
+  UINT8   CoreBlockBiosSignOn[155];
+} VBIOS_VBT_STRUCTURE;
+#pragma pack(pop)
+///
+/// Driver Private Function definitions
+///
+
+/**
+  Graphics OpRegion / Software SCI driver installation function.
+
+  @retval EFI_SUCCESS     - The driver installed without error.
+  @retval EFI_ABORTED     - The driver encountered an error and could not complete
+                            installation of the ACPI tables.
+**/
+EFI_STATUS
+IgdOpRegionInit (
+  VOID
+  );
+
+/**
+  Get Intel video BIOS VBT information (i.e. Pointer to VBT and VBT size).
+  The VBT (Video BIOS Table) is a block of customizable data that is built
+  within the video BIOS and edited by customers.
+
+  @retval EFI_SUCCESS            - Video BIOS VBT information returned.
+  @exception EFI_UNSUPPORTED     - Could not find VBT information (*VBiosVbtPtr = NULL).
+**/
+EFI_STATUS
+GetVBiosVbtEndOfDxe (
+  VOID
+  );
+
+/**
+  Update Graphics OpRegion after PCI enumeration.
+
+  @retval EFI_SUCCESS     - The function completed successfully.
+**/
+EFI_STATUS
+UpdateIgdOpRegionEndOfDxe (
+  VOID
+  );
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/LibraryPrivate/DxeGraphicsInitLib/DxeGraphicsInitLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/LibraryPrivate/DxeGraphicsInitLib/DxeGraphicsInitLib.c
new file mode 100644
index 0000000000..8769f34021
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/LibraryPrivate/DxeGraphicsInitLib/DxeGraphicsInitLib.c
@@ -0,0 +1,135 @@
+/** @file
+  DXE Library for Initializing SystemAgent Graphics ACPI table initialization.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Library/DxeGraphicsInitLib.h>
+
+
+typedef union {
+  struct {
+    UINT32  Low;
+    UINT32  High;
+  } Data32;
+  UINT64 Data;
+} UINT64_STRUCT;
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT64_STRUCT                 mMchBarBase;
+GLOBAL_REMOVE_IF_UNREFERENCED GOP_COMPONENT_NAME2_PROTOCOL  *GopComponentName2Protocol = NULL;
+
+/**
+    Do Post GT PM Init Steps after VBIOS Initialization.
+
+  @retval EFI_SUCCESS          Succeed.
+**/
+EFI_STATUS
+PostPmInitEndOfDxe (
+  VOID
+  )
+{
+  CHAR16                    *DriverVersion;
+  UINTN                     Index;
+  EFI_STATUS                Status;
+  GRAPHICS_DXE_CONFIG       *GraphicsDxeConfig;
+  SA_POLICY_PROTOCOL        *SaPolicy;
+
+  ///
+  /// Get the platform setup policy.
+  ///
+  DriverVersion = NULL;
+  Status = gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID **) &SaPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gGraphicsDxeConfigGuid, (VOID *)&GraphicsDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+
+  Status = gBS->LocateProtocol (&gGopComponentName2ProtocolGuid, NULL, (VOID **)&GopComponentName2Protocol);
+  if (!EFI_ERROR (Status)) {
+    Status = GopComponentName2Protocol->GetDriverVersion (
+                                          GopComponentName2Protocol,
+                                          "en-US",
+                                          &DriverVersion
+                                          );
+    if (!EFI_ERROR (Status)) {
+      for (Index = 0; (DriverVersion[Index] != '\0'); Index++) {
+      }
+      Index = (Index+1)*2;
+      CopyMem (GraphicsDxeConfig->GopVersion, DriverVersion, Index);
+    }
+  }
+
+  ///
+  /// Return final status
+  ///
+  return EFI_SUCCESS;
+}
+
+
+/**
+Initialize GT ACPI tables
+
+  @param[in] ImageHandle -     Handle for the image of this driver
+  @param[in] SaPolicy -        SA DXE Policy protocol
+
+  @retval EFI_SUCCESS          - GT ACPI initialization complete
+  @retval EFI_NOT_FOUND        - Dxe System Table not found.
+  @retval EFI_OUT_OF_RESOURCES - Mmio not allocated successfully.
+**/
+EFI_STATUS
+GraphicsInit (
+  IN EFI_HANDLE              ImageHandle,
+  IN SA_POLICY_PROTOCOL      *SaPolicy
+  )
+{
+  EFI_STATUS                      Status;
+  GRAPHICS_DXE_CONFIG             *GraphicsDxeConfig;
+  SYSTEM_AGENT_NVS_AREA_PROTOCOL  *SaNvsAreaProtocol;
+
+  Status                  = EFI_SUCCESS;
+  mMchBarBase.Data32.High = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, R_SA_MCHBAR + 4));
+  mMchBarBase.Data32.Low  = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, R_SA_MCHBAR));
+  mMchBarBase.Data       &= (UINT64) ~BIT0;
+
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gGraphicsDxeConfigGuid, (VOID *)&GraphicsDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  ///  Locate the SA Global NVS Protocol.
+  ///
+  Status = gBS->LocateProtocol (&gSaNvsAreaProtocolGuid, NULL, (VOID **) &SaNvsAreaProtocol);
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Update IGD SA Global NVS
+  ///
+  DEBUG ((DEBUG_INFO, " Update Igd SA Global NVS Area.\n"));
+
+  SaNvsAreaProtocol->Area->AlsEnable                    = GraphicsDxeConfig->AlsEnable;
+  ///
+  /// Initialize IGD state by checking if IGD Device 2 Function 0 is enabled in the chipset
+  ///
+  if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, R_SA_DEVEN)) & B_SA_DEVEN_D2EN_MASK) {
+    SaNvsAreaProtocol->Area->IgdState = 1;
+  } else {
+    SaNvsAreaProtocol->Area->IgdState = 0;
+  }
+
+  SaNvsAreaProtocol->Area->BrightnessPercentage         = 100;
+  SaNvsAreaProtocol->Area->IgdBootType                  = GraphicsDxeConfig->IgdBootType;
+  SaNvsAreaProtocol->Area->IgdPanelType                 = GraphicsDxeConfig->IgdPanelType;
+  SaNvsAreaProtocol->Area->IgdPanelScaling              = GraphicsDxeConfig->IgdPanelScaling;
+  ///
+  /// Get SFF power mode platform data for the IGD driver.  Flip the bit (bitwise xor)
+  /// since Setup value is opposite of NVS and IGD OpRegion value.
+  ///
+  SaNvsAreaProtocol->Area->IgdDvmtMemSize               = GraphicsDxeConfig->IgdDvmtMemSize;
+  SaNvsAreaProtocol->Area->IgdFunc1Enable               = 0;
+  SaNvsAreaProtocol->Area->IgdHpllVco                   = MmioRead8 (mMchBarBase.Data + 0xC0F) & 0x07;
+  SaNvsAreaProtocol->Area->IgdSciSmiMode                = 0;
+  SaNvsAreaProtocol->Area->GfxTurboIMON                 = GraphicsDxeConfig->GfxTurboIMON;
+  SaNvsAreaProtocol->Area->EdpValid                     = 0;
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/LibraryPrivate/DxeGraphicsInitLib/DxeGraphicsInitLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/LibraryPrivate/DxeGraphicsInitLib/DxeGraphicsInitLib.inf
new file mode 100644
index 0000000000..78c115eb3c
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/LibraryPrivate/DxeGraphicsInitLib/DxeGraphicsInitLib.inf
@@ -0,0 +1,45 @@
+## @file
+# Component description file for the Dxe Graphics Init library.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeGraphicsInitLib
+FILE_GUID = 2E889319-7361-4F6C-B181-EBD7AEF1DE6A
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_DRIVER
+LIBRARY_CLASS = DxeGraphicsInitLib
+
+[LibraryClasses]
+UefiLib
+UefiRuntimeServicesTableLib
+UefiBootServicesTableLib
+DebugLib
+PostCodeLib
+ConfigBlockLib
+IoLib
+PciSegmentLib
+BaseMemoryLib
+MemoryAllocationLib
+MmPciLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Sources]
+DxeGraphicsInitLib.c
+
+[Guids]
+gGraphicsDxeConfigGuid   ## CONSUMES
+
+[Pcd]
+
+[Protocols]
+gSaPolicyProtocolGuid                  ## CONSUMES
+gSaNvsAreaProtocolGuid                 ## CONSUMES
+gGopComponentName2ProtocolGuid         ## CONSUMES
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/LibraryPrivate/DxeGraphicsPolicyLib/DxeGraphicsPolicyLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/LibraryPrivate/DxeGraphicsPolicyLib/DxeGraphicsPolicyLib.c
new file mode 100644
index 0000000000..fd284d5f42
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/LibraryPrivate/DxeGraphicsPolicyLib/DxeGraphicsPolicyLib.c
@@ -0,0 +1,118 @@
+/** @file
+  This file provide services for DXE phase Graphics policy default initialization.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DxeGraphicsPolicyLib.h>
+
+/**
+  This function prints the Graphics DXE phase policy.
+
+  @param[in] SaPolicy - SA DXE Policy protocol
+**/
+VOID
+GraphicsDxePolicyPrint (
+  IN  SA_POLICY_PROTOCOL      *SaPolicy
+  )
+{
+  EFI_STATUS                  Status;
+  GRAPHICS_DXE_CONFIG         *GraphicsDxeConfig;
+
+  //
+  // Get requisite IP Config Blocks which needs to be used here
+  //
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gGraphicsDxeConfigGuid, (VOID *)&GraphicsDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+
+  DEBUG_CODE_BEGIN ();
+  DEBUG ((DEBUG_INFO, "\n------------------------ Graphics Policy (DXE) print BEGIN -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %d\n", GraphicsDxeConfig->Header.Revision));
+  ASSERT (GraphicsDxeConfig->Header.Revision == GRAPHICS_DXE_CONFIG_REVISION);
+  DEBUG ((DEBUG_INFO, "\n------------------------ Graphics Policy (DXE) print END -----------------\n"));
+  DEBUG_CODE_END ();
+
+  return;
+}
+
+
+/**
+  This function Load default Graphics DXE policy.
+
+  @param[in] ConfigBlockPointer    The pointer to add Graphics config block
+**/
+VOID
+LoadIgdDxeDefault (
+  IN VOID    *ConfigBlockPointer
+  )
+{
+  GRAPHICS_DXE_CONFIG        *GraphicsDxeConfig;
+
+  GraphicsDxeConfig = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "GraphicsDxeConfig->Header.GuidHob.Name = %g\n", &GraphicsDxeConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "GraphicsDxeConfig->Header.GuidHob.Header.HobLength = 0x%x\n", GraphicsDxeConfig->Header.GuidHob.Header.HobLength));
+  ///
+  /// Initialize the Graphics configuration
+  ///
+  GraphicsDxeConfig->PlatformConfig           = 1;
+  GraphicsDxeConfig->AlsEnable                = 2;
+  GraphicsDxeConfig->BacklightControlSupport  = 2;
+  GraphicsDxeConfig->IgdBlcConfig             = 2;
+  GraphicsDxeConfig->IgdDvmtMemSize           = 1;
+  GraphicsDxeConfig->GfxTurboIMON             = 31;
+  ///
+  /// <EXAMPLE> Create a static Backlight Brightness Level Duty cycle Mapping Table
+  /// Possible 20 entries (example used 11), each 16 bits as follows:
+  /// [15] = Field Valid bit, [14:08] = Level in Percentage (0-64h), [07:00] = Desired duty cycle (0 - FFh).
+  ///
+  GraphicsDxeConfig->BCLM[0] = (0x0000 + WORD_FIELD_VALID_BIT);  ///< 0%
+  GraphicsDxeConfig->BCLM[1] = (0x0A19 + WORD_FIELD_VALID_BIT);  ///< 10%
+  GraphicsDxeConfig->BCLM[2] = (0x1433 + WORD_FIELD_VALID_BIT);  ///< 20%
+  GraphicsDxeConfig->BCLM[3] = (0x1E4C + WORD_FIELD_VALID_BIT);  ///< 30%
+  GraphicsDxeConfig->BCLM[4] = (0x2866 + WORD_FIELD_VALID_BIT);  ///< 40%
+  GraphicsDxeConfig->BCLM[5] = (0x327F + WORD_FIELD_VALID_BIT);  ///< 50%
+  GraphicsDxeConfig->BCLM[6] = (0x3C99 + WORD_FIELD_VALID_BIT);  ///< 60%
+  GraphicsDxeConfig->BCLM[7] = (0x46B2 + WORD_FIELD_VALID_BIT);  ///< 70%
+  GraphicsDxeConfig->BCLM[8] = (0x50CC + WORD_FIELD_VALID_BIT);  ///< 80%
+  GraphicsDxeConfig->BCLM[9] = (0x5AE5 + WORD_FIELD_VALID_BIT);  ///< 90%
+  GraphicsDxeConfig->BCLM[10] = (0x64FF + WORD_FIELD_VALID_BIT);  ///< 100%
+}
+
+static COMPONENT_BLOCK_ENTRY  mGraphicsDxeIpBlocks = {
+  &gGraphicsDxeConfigGuid, sizeof (GRAPHICS_DXE_CONFIG), GRAPHICS_DXE_CONFIG_REVISION, LoadIgdDxeDefault};
+
+
+/**
+  Get DXE Graphics config block table total size.
+
+  @retval     Size of DXE Graphics config block table
+**/
+UINT16
+EFIAPI
+GraphicsGetConfigBlockTotalSizeDxe (
+  VOID
+  )
+{
+  return mGraphicsDxeIpBlocks.Size;
+}
+
+/**
+  GraphicsAddConfigBlocksDxe add all DXE Graphics config block.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add SA config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+GraphicsAddConfigBlocksDxe (
+  IN VOID           *ConfigBlockTableAddress
+  )
+{
+  EFI_STATUS  Status;
+  Status = AddComponentConfigBlocks (ConfigBlockTableAddress, &mGraphicsDxeIpBlocks, 1);
+  return Status;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/LibraryPrivate/DxeGraphicsPolicyLib/DxeGraphicsPolicyLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/LibraryPrivate/DxeGraphicsPolicyLib/DxeGraphicsPolicyLib.inf
new file mode 100644
index 0000000000..d3ac3c24a1
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/LibraryPrivate/DxeGraphicsPolicyLib/DxeGraphicsPolicyLib.inf
@@ -0,0 +1,37 @@
+## @file
+# Component description file for the DXE Graphics Policy Init library.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeGraphicsPolicyLib
+FILE_GUID = C6190599-287E-40F9-9B46-EE112A322EBF
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = DxeGraphicsPolicyLib
+
+[LibraryClasses]
+BaseMemoryLib
+UefiRuntimeServicesTableLib
+UefiBootServicesTableLib
+DebugLib
+PostCodeLib
+ConfigBlockLib
+HobLib
+SiConfigBlockLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Sources]
+DxeGraphicsPolicyLib.c
+
+[Guids]
+gGraphicsDxeConfigGuid
+
+[Pcd]
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/LibraryPrivate/DxeIgdOpRegionInitLib/DxeIgdOpRegionInit.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/LibraryPrivate/DxeIgdOpRegionInitLib/DxeIgdOpRegionInit.c
new file mode 100644
index 0000000000..0e12f62f4e
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/LibraryPrivate/DxeIgdOpRegionInitLib/DxeIgdOpRegionInit.c
@@ -0,0 +1,541 @@
+/** @file
+  This is part of the implementation of an Intel Graphics drivers OpRegion /
+  Software SCI interface between system BIOS, ASL code, and Graphics drivers.
+  The code in this file will load the driver and initialize the interface
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DxeIgdOpRegionInitLib.h>
+
+#define HEADER_OPREGION_VER_GEN9          0x0200
+#define HEADER_OPREGION_VER_GEN12         0x0201
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED IGD_OPREGION_PROTOCOL           mIgdOpRegion;
+
+/**
+  Get VBT data using SaPlaformPolicy
+
+  @param[out] VbtFileBuffer    Pointer to VBT data buffer.
+
+  @retval EFI_SUCCESS      VBT data was returned.
+  @retval EFI_NOT_FOUND    VBT data not found.
+  @exception EFI_UNSUPPORTED  Invalid signature in VBT data.
+**/
+EFI_STATUS
+GetIntegratedIntelVbtPtr (
+  OUT VBIOS_VBT_STRUCTURE **VbtFileBuffer
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_PHYSICAL_ADDRESS          VbtAddress;
+  UINT32                        Size;
+  GRAPHICS_DXE_CONFIG           *GraphicsDxeConfig;
+  SA_POLICY_PROTOCOL            *SaPolicy;
+
+  ///
+  /// Get the SA policy.
+  ///
+  Status = gBS->LocateProtocol (
+                  &gSaPolicyProtocolGuid,
+                  NULL,
+                  (VOID **) &SaPolicy
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gGraphicsDxeConfigGuid, (VOID *)&GraphicsDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  VbtAddress = GraphicsDxeConfig->VbtAddress;
+  Size       = GraphicsDxeConfig->Size;
+
+  if (VbtAddress == 0x00000000) {
+    return EFI_NOT_FOUND;
+  } else {
+    ///
+    /// Check VBT signature
+    ///
+    *VbtFileBuffer  = NULL;
+    *VbtFileBuffer = (VBIOS_VBT_STRUCTURE *) (UINTN) VbtAddress;
+    if ((*((UINT32 *) ((*VbtFileBuffer)->HeaderSignature))) != VBT_SIGNATURE) {
+      FreePool (*VbtFileBuffer);
+      *VbtFileBuffer = NULL;
+      return EFI_UNSUPPORTED;
+    }
+  }
+  if (Size == 0) {
+    return EFI_NOT_FOUND;
+  } else {
+    ///
+    /// Check VBT size
+    ///
+    if ((*VbtFileBuffer)->HeaderVbtSize > Size) {
+      (*VbtFileBuffer)->HeaderVbtSize = (UINT16) Size;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  Get a pointer to an uncompressed image of the Intel video BIOS.
+
+  @Note: This function would only be called if the video BIOS at 0xC000 is
+         missing or not an Intel video BIOS.  It may not be an Intel video BIOS
+         if the Intel graphic contoller is considered a secondary adapter.
+
+  @param[out] VBiosImage     - Pointer to an uncompressed Intel video BIOS.  This pointer must
+                               be set to NULL if an uncompressed image of the Intel Video BIOS
+                               is not obtainable.
+
+  @retval EFI_SUCCESS        - VBiosPtr is updated.
+  @exception EFI_UNSUPPORTED - No Intel video BIOS found.
+**/
+EFI_STATUS
+GetIntegratedIntelVBiosPtr (
+  OUT INTEL_VBIOS_OPTION_ROM_HEADER **VBiosImage
+  )
+{
+  EFI_HANDLE                    *HandleBuffer;
+  UINTN                         HandleCount;
+  UINTN                         Index;
+  INTEL_VBIOS_PCIR_STRUCTURE    *PcirBlockPtr;
+  EFI_STATUS                    Status;
+  EFI_PCI_IO_PROTOCOL           *PciIo;
+  INTEL_VBIOS_OPTION_ROM_HEADER *VBiosRomImage;
+
+  ///
+  /// Set as if an umcompressed Intel video BIOS image was not obtainable.
+  ///
+  VBiosRomImage = NULL;
+
+  ///
+  /// Get all PCI IO protocols
+  ///
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiPciIoProtocolGuid,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuffer
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Find the video BIOS by checking each PCI IO handle for an Intel video
+  /// BIOS OPROM.
+  ///
+  for (Index = 0; Index < HandleCount; Index++) {
+    Status = gBS->HandleProtocol (
+                    HandleBuffer[Index],
+                    &gEfiPciIoProtocolGuid,
+                    (VOID **) &PciIo
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    VBiosRomImage = PciIo->RomImage;
+
+    ///
+    /// If this PCI device doesn't have a ROM image, skip to the next device.
+    ///
+    if (!VBiosRomImage) {
+      continue;
+    }
+    ///
+    /// Get pointer to PCIR structure
+    ///
+    PcirBlockPtr = (INTEL_VBIOS_PCIR_STRUCTURE *) ((UINT8 *) VBiosRomImage + VBiosRomImage->PcirOffset);
+
+    ///
+    /// Check if we have an Intel video BIOS OPROM.
+    ///
+    if ((VBiosRomImage->Signature == OPTION_ROM_SIGNATURE) &&
+        (PcirBlockPtr->VendorId == V_SA_MC_VID) &&
+        (PcirBlockPtr->ClassCode[0] == 0x00) &&
+        (PcirBlockPtr->ClassCode[1] == 0x00) &&
+        (PcirBlockPtr->ClassCode[2] == 0x03)
+        ) {
+      ///
+      /// Found Intel video BIOS.
+      ///
+      *VBiosImage = VBiosRomImage;
+      return EFI_SUCCESS;
+    }
+  }
+  ///
+  /// No Intel video BIOS found.
+  ///
+  ///
+  /// Free any allocated buffers
+  ///
+  FreePool (HandleBuffer);
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Get Intel video BIOS VBT information (i.e. Pointer to VBT and VBT size).
+  The VBT (Video BIOS Table) is a block of customizable data that is built
+  within the video BIOS and edited by customers.
+
+  @retval EFI_SUCCESS            - Video BIOS VBT information returned.
+  @exception EFI_UNSUPPORTED     - Could not find VBT information (*VBiosVbtPtr = NULL).
+**/
+EFI_STATUS
+GetVBiosVbtEndOfDxe (
+  VOID
+  )
+{
+  INTEL_VBIOS_OPTION_ROM_HEADER *VBiosPtr;
+  VBIOS_VBT_STRUCTURE           *VBiosVbtPtr;
+  EFI_STATUS                    Status;
+  VBIOS_VBT_STRUCTURE           *VbtFileBuffer;
+  GRAPHICS_DXE_CONFIG           *GraphicsDxeConfig;
+  SA_POLICY_PROTOCOL            *SaPolicy;
+
+  VbtFileBuffer = NULL;
+
+  ///
+  /// Get the SA policy.
+  ///
+  Status = gBS->LocateProtocol (
+                  &gSaPolicyProtocolGuid,
+                  NULL,
+                  (VOID **) &SaPolicy
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gGraphicsDxeConfigGuid, (VOID *)&GraphicsDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  VBiosPtr = NULL;
+  ///
+  /// Try to get VBT from FV.
+  ///
+  GetIntegratedIntelVbtPtr (&VbtFileBuffer);
+  if (VbtFileBuffer != NULL) {
+    ///
+    /// Video BIOS not found, use VBT from SaPolicy
+    ///
+    DEBUG ((DEBUG_INFO, "VBT data found\n"));
+    CopyMem (mIgdOpRegion.OpRegion->Header.DVER, GraphicsDxeConfig->GopVersion, sizeof(GraphicsDxeConfig->GopVersion));
+    mIgdOpRegion.OpRegion->MBox3.RVDA = 0;
+    mIgdOpRegion.OpRegion->MBox3.RVDS = 0;
+    if ((VbtFileBuffer->HeaderVbtSize > 0x1800)) {  // VBT > 6KB
+      DEBUG ((DEBUG_INFO, "Extended VBT supported\n"));
+      mIgdOpRegion.OpRegion->MBox3.RVDA = sizeof (IGD_OPREGION_STRUCTURE); // Relative offset at the end of Op-region.
+      mIgdOpRegion.OpRegion->MBox3.RVDS = ((VbtFileBuffer->HeaderVbtSize) & (UINT32)~(0x1FF)) + 0x200; // Aligned VBT Data Size to 512 bytes.
+      CopyMem ((CHAR8 *)(UINTN)(mIgdOpRegion.OpRegion) + sizeof (IGD_OPREGION_STRUCTURE), VbtFileBuffer, mIgdOpRegion.OpRegion->MBox3.RVDS);
+    } else {
+      CopyMem (mIgdOpRegion.OpRegion->MBox4.RVBT, VbtFileBuffer, VbtFileBuffer->HeaderVbtSize);
+    }
+    return EFI_SUCCESS;
+  }
+
+  if (VBiosPtr == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  DEBUG ((DEBUG_INFO, "VBIOS found at 0x%X\n", VBiosPtr));
+  VBiosVbtPtr = (VBIOS_VBT_STRUCTURE *) ((UINT8 *) VBiosPtr + VBiosPtr->VbtOffset);
+
+  if ((*((UINT32 *) (VBiosVbtPtr->HeaderSignature))) != VBT_SIGNATURE) {
+    return EFI_UNSUPPORTED;
+  }
+
+  ///
+  /// Initialize Video BIOS version with its build number.
+  ///
+  mIgdOpRegion.OpRegion->Header.VVER[0] = VBiosVbtPtr->CoreBlockBiosBuild[0];
+  mIgdOpRegion.OpRegion->Header.VVER[1] = VBiosVbtPtr->CoreBlockBiosBuild[1];
+  mIgdOpRegion.OpRegion->Header.VVER[2] = VBiosVbtPtr->CoreBlockBiosBuild[2];
+  mIgdOpRegion.OpRegion->Header.VVER[3] = VBiosVbtPtr->CoreBlockBiosBuild[3];
+  CopyMem (mIgdOpRegion.OpRegion->MBox4.RVBT, VBiosVbtPtr, VBiosVbtPtr->HeaderVbtSize);
+
+  ///
+  /// Return final status
+  ///
+  return EFI_SUCCESS;
+}
+
+/**
+  Graphics OpRegion / Software SCI driver installation function.
+
+  @param[in] void         - None
+  @retval EFI_SUCCESS     - The driver installed without error.
+  @retval EFI_ABORTED     - The driver encountered an error and could not complete
+                            installation of the ACPI tables.
+**/
+EFI_STATUS
+IgdOpRegionInit (
+  VOID
+  )
+{
+  EFI_HANDLE                      Handle;
+  EFI_STATUS                      Status;
+  UINT32                          DwordData;
+  UINT64                          IgdBaseAddress;
+  SA_POLICY_PROTOCOL              *SaPolicy;
+  GRAPHICS_DXE_CONFIG             *GraphicsDxeConfig;
+  UINT8                           Index;
+  SYSTEM_AGENT_NVS_AREA_PROTOCOL  *SaNvsAreaProtocol;
+  VBIOS_VBT_STRUCTURE             *VbtFileBuffer;
+  UINT16                          ExtendedVbtSize;
+
+  ///
+  /// Get the SA policy.
+  ///
+  Status = gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID **)&SaPolicy);
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gGraphicsDxeConfigGuid, (VOID *)&GraphicsDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  VbtFileBuffer = NULL;
+  ExtendedVbtSize = 0;
+
+  GetIntegratedIntelVbtPtr (&VbtFileBuffer);
+  ///
+  ///  Locate the SA Global NVS Protocol.
+  ///
+  Status = gBS->LocateProtocol (
+                  &gSaNvsAreaProtocolGuid,
+                  NULL,
+                  (VOID **) &SaNvsAreaProtocol
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Check if VBT size is >6KB then allocate an ACPI NVS memory buffer as the IGD OpRegion + extended VBT size,
+  /// zero initialize it, and set the IGD OpRegion pointer in the Global NVS area structure.
+  ///
+  if ((VbtFileBuffer != NULL) && (VbtFileBuffer->HeaderVbtSize > 0x1800)) {
+    ExtendedVbtSize = ((VbtFileBuffer->HeaderVbtSize) & (UINT32)~(0x1FF)) + 0x200;
+  }
+
+  Status = (gBS->AllocatePool) (EfiACPIMemoryNVS, sizeof (IGD_OPREGION_STRUCTURE) + ExtendedVbtSize, (VOID **) &mIgdOpRegion.OpRegion);
+  ASSERT_EFI_ERROR (Status);
+  SetMem (mIgdOpRegion.OpRegion, sizeof (IGD_OPREGION_STRUCTURE) + ExtendedVbtSize, 0);
+  SaNvsAreaProtocol->Area->IgdOpRegionAddress = (UINT32) (UINTN) (mIgdOpRegion.OpRegion);
+
+  ///
+  /// If IGD is disabled return
+  ///
+  IgdBaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, IGD_BUS_NUM, IGD_DEV_NUM, IGD_FUN_NUM, 0);
+  if (PciSegmentRead32 (IgdBaseAddress + 0) == 0xFFFFFFFF) {
+    return EFI_SUCCESS;
+  }
+  ///
+  /// Initialize OpRegion Header
+  ///
+  CopyMem (mIgdOpRegion.OpRegion->Header.SIGN, HEADER_SIGNATURE, sizeof (HEADER_SIGNATURE));
+  ///
+  /// Set OpRegion Size in KBs
+  ///
+  mIgdOpRegion.OpRegion->Header.SIZE = HEADER_SIZE / 1024;
+  mIgdOpRegion.OpRegion->Header.OVER = (UINT32) (LShiftU64 (HEADER_OPREGION_VER_GEN12, 16) + LShiftU64 (HEADER_OPREGION_REV, 8));
+
+  ///
+  /// All Mailboxes are supported.
+  ///
+  mIgdOpRegion.OpRegion->Header.MBOX = HEADER_MBOX_SUPPORT;
+
+  ///
+  /// Initialize OpRegion Mailbox 1 (Public ACPI Methods).
+  ///
+  /// Note - The initial setting of mailbox 1 fields is implementation specific.
+  /// Adjust them as needed many even coming from user setting in setup.
+  ///
+  ///
+  /// Initialize OpRegion Mailbox 3 (ASLE Interrupt and Power Conservation).
+  ///
+  /// Note - The initial setting of mailbox 3 fields is implementation specific.
+  /// Adjust them as needed many even coming from user setting in setup.
+  ///
+  ///
+  /// Do not initialize TCHE. This field is written by the graphics driver only.
+  ///
+  ///
+  /// The ALSI field is generally initialized by ASL code by reading the embedded controller.
+  ///
+  mIgdOpRegion.OpRegion->Header.PCON = GraphicsDxeConfig->PlatformConfig;
+  mIgdOpRegion.OpRegion->Header.PCON = mIgdOpRegion.OpRegion->Header.PCON | 0x2;
+
+  mIgdOpRegion.OpRegion->MBox3.BCLP = BACKLIGHT_BRIGHTNESS;
+
+  mIgdOpRegion.OpRegion->MBox3.PFIT = (FIELD_VALID_BIT | PFIT_STRETCH);
+
+  ///
+  /// Reporting to driver for VR IMON Calibration. Bits [5-1] values supported 14A to 31A.
+  ///
+  mIgdOpRegion.OpRegion->MBox3.PCFT = (SaNvsAreaProtocol->Area->GfxTurboIMON << 1) & 0x003E;
+
+  ///
+  /// Set Initial current Brightness
+  ///
+  mIgdOpRegion.OpRegion->MBox3.CBLV = (INIT_BRIGHT_LEVEL | FIELD_VALID_BIT);
+
+  ///
+  /// Static Backlight Brightness Level Duty cycle Mapping Table
+  ///
+  for (Index = 0; Index < MAX_BCLM_ENTRIES; Index++) {
+    mIgdOpRegion.OpRegion->MBox3.BCLM[Index] = GraphicsDxeConfig->BCLM[Index];
+  }
+
+  mIgdOpRegion.OpRegion->MBox3.IUER = 0x00;
+
+  if (!EFI_ERROR (Status)) {
+    mIgdOpRegion.OpRegion->MBox3.IUER =  GraphicsDxeConfig->IuerStatusVal;
+  }
+
+  ///
+  /// Initialize hardware state:
+  ///   Set ASLS Register to the OpRegion physical memory address.
+  ///   Set SWSCI register bit 15 to a "1" to activate SCI interrupts.
+  ///
+  PciSegmentWrite32 (IgdBaseAddress + R_SA_IGD_ASLS_OFFSET, (UINT32) (UINTN) (mIgdOpRegion.OpRegion));
+  PciSegmentAndThenOr16 (IgdBaseAddress + R_SA_IGD_SWSCI_OFFSET, (UINT16) ~(BIT0), BIT15);
+
+  DwordData = PciSegmentRead32 (IgdBaseAddress + R_SA_IGD_ASLS_OFFSET);
+  S3BootScriptSaveMemWrite (
+    S3BootScriptWidthUint32,
+    (UINTN) PcdGet64 (PcdPciExpressBaseAddress) + (IgdBaseAddress + R_SA_IGD_ASLS_OFFSET),
+    1,
+    &DwordData
+    );
+  DwordData = PciSegmentRead32 (IgdBaseAddress + R_SA_IGD_SWSCI_OFFSET);
+  S3BootScriptSaveMemWrite (
+    S3BootScriptWidthUint32,
+    (UINTN) PcdGet64 (PcdPciExpressBaseAddress) + (IgdBaseAddress + R_SA_IGD_SWSCI_OFFSET),
+    1,
+    &DwordData
+    );
+
+  ///
+  /// Install OpRegion / Software SCI protocol
+  ///
+  Handle = NULL;
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Handle,
+                  &gIgdOpRegionProtocolGuid,
+                  &mIgdOpRegion,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Return final status
+  ///
+  return EFI_SUCCESS;
+}
+
+/**
+  Update Graphics OpRegion after PCI enumeration.
+
+  @param[in] void         - None
+  @retval EFI_SUCCESS     - The function completed successfully.
+**/
+EFI_STATUS
+UpdateIgdOpRegionEndOfDxe (
+  VOID
+  )
+{
+  EFI_STATUS                    Status;
+  UINTN                         HandleCount;
+  EFI_HANDLE                    *HandleBuffer;
+  UINTN                         Index;
+  EFI_PCI_IO_PROTOCOL           *PciIo;
+  PCI_TYPE00                    Pci;
+  UINTN                         Segment;
+  UINTN                         Bus;
+  UINTN                         Device;
+  UINTN                         Function;
+
+  Bus      = 0;
+  Device   = 0;
+  Function = 0;
+
+  DEBUG ((DEBUG_INFO, "UpdateIgdOpRegionEndOfDxe\n"));
+
+  mIgdOpRegion.OpRegion->Header.PCON |= BIT8; //Set External Gfx Adapter field is valid
+  mIgdOpRegion.OpRegion->Header.PCON &= (UINT32) (~BIT7); //Assume No External Gfx Adapter
+
+  ///
+  /// Get all PCI IO protocols handles
+  ///
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiPciIoProtocolGuid,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuffer
+                  );
+
+  if (!EFI_ERROR (Status)) {
+    for (Index = 0; Index < HandleCount; Index++) {
+      ///
+      /// Get the PCI IO Protocol Interface corresponding to each handle
+      ///
+      Status = gBS->HandleProtocol (
+                      HandleBuffer[Index],
+                      &gEfiPciIoProtocolGuid,
+                      (VOID **) &PciIo
+                      );
+
+      if (!EFI_ERROR (Status)) {
+        ///
+        /// Read the PCI configuration space
+        ///
+        Status = PciIo->Pci.Read (
+                              PciIo,
+                              EfiPciIoWidthUint32,
+                              0,
+                              sizeof (Pci) / sizeof (UINT32),
+                              &Pci
+                              );
+
+        ///
+        /// Find the display controllers devices
+        ///
+        if (!EFI_ERROR (Status) && IS_PCI_DISPLAY (&Pci)) {
+          Status = PciIo->GetLocation (
+                            PciIo,
+                            &Segment,
+                            &Bus,
+                            &Device,
+                            &Function
+                            );
+
+          //
+          // Assumption: Onboard devices will be sits on Bus no 0, while external devices will be sits on Bus no > 0
+          //
+          if (!EFI_ERROR (Status) && (Bus > 0)) {
+            //External Gfx Adapter Detected and Available
+            DEBUG ((DEBUG_INFO, "PCON - External Gfx Adapter Detected and Available\n"));
+            mIgdOpRegion.OpRegion->Header.PCON |= BIT7;
+            break;
+          }
+        }
+      }
+    }
+  }
+
+  ///
+  /// Free any allocated buffers
+  ///
+  if (HandleBuffer != NULL) {
+    FreePool (HandleBuffer);
+  }
+
+  ///
+  /// Return final status
+  ///
+  return Status;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/LibraryPrivate/DxeIgdOpRegionInitLib/DxeIgdOpRegionInitLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/LibraryPrivate/DxeIgdOpRegionInitLib/DxeIgdOpRegionInitLib.inf
new file mode 100644
index 0000000000..20c6265d8f
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Graphics/LibraryPrivate/DxeIgdOpRegionInitLib/DxeIgdOpRegionInitLib.inf
@@ -0,0 +1,49 @@
+## @file
+# Component description file for the Dxe IGD OpRegion library.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeIgdOpRegionInitLib
+FILE_GUID = 18D47D72-555E-475B-A4E4-AD20C3BD8B15
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_DRIVER
+UEFI_SPECIFICATION_VERSION = 2.00
+LIBRARY_CLASS = DxeIgdOpRegionInitLib
+
+[LibraryClasses]
+UefiLib
+UefiRuntimeServicesTableLib
+UefiBootServicesTableLib
+DebugLib
+PostCodeLib
+ConfigBlockLib
+PciSegmentLib
+BaseMemoryLib
+MemoryAllocationLib
+IoLib
+S3BootScriptLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+IntelSiliconPkg/IntelSiliconPkg.dec
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+[Sources]
+DxeIgdOpRegionInit.c
+
+[Guids]
+gGraphicsDxeConfigGuid        ## CONSUMES
+
+[Protocols]
+gIgdOpRegionProtocolGuid               ## PRODUCES
+gSaPolicyProtocolGuid                  ## CONSUMES
+gEfiPciIoProtocolGuid                  ## CONSUMES
+gSaNvsAreaProtocolGuid                 ## CONSUMES
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 19/40] TigerlakeSiliconPkg/IpBlock: Add Hda component
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (16 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 18/40] TigerlakeSiliconPkg/IpBlock: Add Graphics component Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 20/40] TigerlakeSiliconPkg/IpBlock: Add HostBridge component Heng Luo
                   ` (20 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * IpBlock/Hda/IncludePrivate
  * IpBlock/Hda/Library
  * IpBlock/Hda/LibraryPrivate

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Hda/IncludePrivate/Library/DxeHdaPolicyLib.h           |  55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Hda/IncludePrivate/Register/HdaRegs.h                  |  46 ++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Hda/Library/DxeHdaNhltLib/DxeHdaNhltLib.c              | 383 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Hda/Library/DxeHdaNhltLib/DxeHdaNhltLib.inf            |  31 +++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Hda/LibraryPrivate/DxeHdaPolicyLib/DxeHdaPolicyLib.c   |  92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Hda/LibraryPrivate/DxeHdaPolicyLib/DxeHdaPolicyLib.inf |  31 +++++++++++++++++++++++++++++++
 6 files changed, 638 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Hda/IncludePrivate/Library/DxeHdaPolicyLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Hda/IncludePrivate/Library/DxeHdaPolicyLib.h
new file mode 100644
index 0000000000..9c42bf5611
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Hda/IncludePrivate/Library/DxeHdaPolicyLib.h
@@ -0,0 +1,55 @@
+/** @file
+  DXE Hda policy library.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _DXE_HDA_POLICY_LIB_H_
+#define _DXE_HDA_POLICY_LIB_H_
+
+#include <Protocol/PchPolicy.h>
+
+/**
+  Print HDAUDIO_DXE_CONFIG and serial out.
+
+  @param[in] PchPolicy            Pointer to a PCH_POLICY_PROTOCOL
+**/
+VOID
+HdaDxePrintConfig (
+  IN PCH_POLICY_PROTOCOL    *PchPolicy
+  );
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+HdaDxeLoadConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  );
+
+/**
+  Get Hda config block table size.
+
+  @retval      Size of config block
+**/
+UINT16
+HdaDxeGetConfigBlockTotalSize (
+  VOID
+  );
+
+/**
+  Add Hda ConfigBlock.
+
+  @param[in] ConfigBlockTableAddress    The pointer to config block table
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+HdaDxeAddConfigBlock (
+  IN VOID           *ConfigBlockTableAddress
+  );
+
+#endif // _DXE_HDA_POLICY_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Hda/IncludePrivate/Register/HdaRegs.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Hda/IncludePrivate/Register/HdaRegs.h
new file mode 100644
index 0000000000..b165e7bb22
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Hda/IncludePrivate/Register/HdaRegs.h
@@ -0,0 +1,46 @@
+/** @file
+  Register names for High Definition Audio device.
+
+  Conventions:
+
+  - Register definition format:
+    Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpace_RegisterName
+  - Prefix:
+    Definitions beginning with "R_" are registers
+    Definitions beginning with "B_" are bits within registers
+    Definitions beginning with "V_" are meaningful values within the bits
+    Definitions beginning with "S_" are register size
+    Definitions beginning with "N_" are the bit position
+  - [GenerationName]:
+    Three letter acronym of the generation is used (e.g. SKL,KBL,CNL etc.).
+    Register name without GenerationName applies to all generations.
+  - [ComponentName]:
+    This field indicates the component name that the register belongs to (e.g. PCH, SA etc.)
+    Register name without ComponentName applies to all components.
+    Register that is specific to -LP denoted by "_PCH_LP_" in component name.
+  - SubsystemName:
+    This field indicates the subsystem name of the component that the register belongs to
+    (e.g. PCIE, USB, SATA, GPIO, PMC etc.).
+  - RegisterSpace:
+    MEM - MMIO space register of subsystem.
+    IO  - IO space register of subsystem.
+    PCR - Private configuration register of subsystem.
+    CFG - PCI configuration space register of subsystem.
+  - RegisterName:
+    Full register name.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _HDA_REGS_H_
+#define _HDA_REGS_H_
+
+//
+// HD-A Controller Registers
+//
+// PCI Configuration Space Registers
+//
+#define R_HDA_CFG_PCS                           0x54
+#define B_HDA_CFG_PCS_PMEE                      BIT8
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Hda/Library/DxeHdaNhltLib/DxeHdaNhltLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Hda/Library/DxeHdaNhltLib/DxeHdaNhltLib.c
new file mode 100644
index 0000000000..71388934e6
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Hda/Library/DxeHdaNhltLib/DxeHdaNhltLib.c
@@ -0,0 +1,383 @@
+/** @file
+  HD Audio NHLT Library implementation.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PcdLib.h>
+#include <ConfigBlock.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PchInfoLib.h>
+#include <DxeHdaNhlt.h>
+
+/**
+  Returns pointer to Endpoint ENDPOINT_DESCRIPTOR structure.
+
+  @param[in] *NhltTable    Endpoint for which Format address is retrieved
+  @param[in] FormatIndex   Index of Format to be retrieved
+
+  @retval                  Pointer to ENDPOINT_DESCRIPTOR structure with given index
+**/
+ENDPOINT_DESCRIPTOR *
+GetNhltEndpoint (
+  IN CONST NHLT_ACPI_TABLE      *NhltTable,
+  IN CONST UINT8                EndpointIndex
+  )
+{
+  UINT8               Index;
+  ENDPOINT_DESCRIPTOR *Endpoint;
+  Endpoint = (ENDPOINT_DESCRIPTOR*) (NhltTable->EndpointDescriptors);
+
+  if (EndpointIndex > NhltTable->EndpointCount) {
+    return NULL;
+  }
+
+  for (Index = 0; Index < EndpointIndex; Index++) {
+    Endpoint = (ENDPOINT_DESCRIPTOR*) ((UINT8*) (Endpoint) + Endpoint->EndpointDescriptorLength);
+  }
+
+  return Endpoint;
+}
+
+/**
+  Returns pointer to Endpoint Specific Configuration SPECIFIC_CONFIG structure.
+
+  @param[in] *Endpoint     Endpoint for which config address is retrieved
+
+  @retval                  Pointer to SPECIFIC_CONFIG structure with endpoint's capabilities
+**/
+SPECIFIC_CONFIG *
+GetNhltEndpointDeviceCapabilities (
+  IN CONST ENDPOINT_DESCRIPTOR  *Endpoint
+  )
+{
+  return (SPECIFIC_CONFIG*) (&Endpoint->EndpointConfig);
+}
+
+/**
+  Returns pointer to all Formats Configuration FORMATS_CONFIG structure.
+
+  @param[in] *Endpoint     Endpoint for which Formats address is retrieved
+
+  @retval                  Pointer to FORMATS_CONFIG structure
+**/
+FORMATS_CONFIG *
+GetNhltEndpointFormatsConfig (
+  IN CONST ENDPOINT_DESCRIPTOR  *Endpoint
+  )
+{
+  FORMATS_CONFIG *FormatsConfig;
+  FormatsConfig = (FORMATS_CONFIG*) ((UINT8*) (&Endpoint->EndpointConfig)
+                                     + sizeof (Endpoint->EndpointConfig.CapabilitiesSize)
+                                     + Endpoint->EndpointConfig.CapabilitiesSize);
+
+  return FormatsConfig;
+}
+
+/**
+  Returns pointer to Format Configuration FORMAT_CONFIG structure.
+
+  @param[in] *Endpoint     Endpoint for which Format address is retrieved
+  @param[in] FormatIndex   Index of Format to be retrieved
+
+  @retval                  Pointer to FORMAT_CONFIG structure with given index
+**/
+FORMAT_CONFIG *
+GetNhltEndpointFormat (
+  IN CONST ENDPOINT_DESCRIPTOR  *Endpoint,
+  IN CONST UINT8                FormatIndex
+  )
+{
+  UINT8          Index;
+  UINT32         Length;
+  FORMATS_CONFIG *FormatsConfig;
+  FORMAT_CONFIG  *Format;
+
+  Length = 0;
+  FormatsConfig = GetNhltEndpointFormatsConfig (Endpoint);
+  Format = FormatsConfig->FormatsConfiguration;
+
+  if (FormatIndex > FormatsConfig->FormatsCount) {
+    return NULL;
+  }
+
+  for (Index = 0; Index < FormatIndex; Index++) {
+    Length = sizeof (Format->Format) + Format->FormatConfiguration.CapabilitiesSize
+      + sizeof (Format->FormatConfiguration.CapabilitiesSize);
+    Format = (FORMAT_CONFIG*) ((UINT8*) (Format) + Length);
+  }
+
+  return Format;
+}
+
+/**
+  Returns pointer to all Device Information DEVICES_INFO structure.
+
+  @param[in] *Endpoint     Endpoint for which DevicesInfo address is retrieved
+
+  @retval                  Pointer to DEVICES_INFO structure
+**/
+DEVICES_INFO *
+GetNhltEndpointDevicesInfo (
+  IN CONST ENDPOINT_DESCRIPTOR  *Endpoint
+  )
+{
+  DEVICES_INFO   *DevicesInfo;
+  FORMATS_CONFIG *FormatsConfig;
+  FORMAT_CONFIG  *Format;
+
+  FormatsConfig = GetNhltEndpointFormatsConfig (Endpoint);
+  Format = GetNhltEndpointFormat (Endpoint, FormatsConfig->FormatsCount);
+  DevicesInfo = (DEVICES_INFO*) ((UINT8*) Format);
+
+  return DevicesInfo;
+}
+
+/**
+  Returns pointer to Device Information DEVICES_INFO structure.
+
+  @param[in] *Endpoint       Endpoint for which Device Info address is retrieved
+  @param[in] DeviceInfoIndex Index of Device Info to be retrieved
+
+  @retval                    Pointer to DEVICE_INFO structure with given index
+**/
+DEVICE_INFO *
+GetNhltEndpointDeviceInfo (
+  IN CONST ENDPOINT_DESCRIPTOR  *Endpoint,
+  IN CONST UINT8                DeviceInfoIndex
+  )
+{
+  DEVICES_INFO  *DevicesInfo;
+  DEVICE_INFO   *DeviceInfo;
+
+  DevicesInfo = GetNhltEndpointDevicesInfo (Endpoint);
+  DeviceInfo = DevicesInfo->DeviceInformation;
+
+  if (DevicesInfo == NULL || DeviceInfoIndex >= DevicesInfo->DeviceInfoCount) {
+    return NULL;
+  }
+
+  DeviceInfo = (DEVICE_INFO*) ((UINT8*) (DeviceInfo) + sizeof (*DeviceInfo) * DeviceInfoIndex);
+
+  return DeviceInfo;
+}
+
+/**
+  Returns pointer to OED Configuration SPECIFIC_CONFIG structure.
+
+  @param[in] *NhltTable    NHLT table for which OED address is retrieved
+
+  @retval                  Pointer to SPECIFIC_CONFIG structure with NHLT capabilities
+**/
+SPECIFIC_CONFIG *
+GetNhltOedConfig (
+  IN CONST NHLT_ACPI_TABLE      *NhltTable
+  )
+{
+  ENDPOINT_DESCRIPTOR *Endpoint;
+  SPECIFIC_CONFIG     *OedConfig;
+
+  Endpoint = GetNhltEndpoint (NhltTable, (NhltTable->EndpointCount));
+  OedConfig = (SPECIFIC_CONFIG*) ((UINT8*) (Endpoint));
+
+  return OedConfig;
+}
+
+/**
+  Prints Format configuration.
+
+  @param[in] *Format       Format to be printed
+
+  @retval None
+**/
+VOID
+NhltFormatDump (
+  IN CONST FORMAT_CONFIG        *Format
+  )
+{
+  UINT32 Index;
+
+  DEBUG ((DEBUG_INFO, "------------------------------- FORMAT -------------------------------\n"));
+  DEBUG ((DEBUG_INFO, " Format->Format.Format.wFormatTag      = 0x%x\n", Format->Format.Format.wFormatTag));
+  DEBUG ((DEBUG_INFO, " Format->Format.Format.nChannels       = %d\n", Format->Format.Format.nChannels));
+  DEBUG ((DEBUG_INFO, " Format->Format.Format.nSamplesPerSec  = %d\n", Format->Format.Format.nSamplesPerSec));
+  DEBUG ((DEBUG_INFO, " Format->Format.Format.nAvgBytesPerSec = %d\n", Format->Format.Format.nAvgBytesPerSec));
+  DEBUG ((DEBUG_INFO, " Format->Format.Format.nBlockAlign     = %d\n", Format->Format.Format.nBlockAlign));
+  DEBUG ((DEBUG_INFO, " Format->Format.Format.wBitsPerSample  = %d\n", Format->Format.Format.wBitsPerSample));
+  DEBUG ((DEBUG_INFO, " Format->Format.Format.cbSize          = %d\n", Format->Format.Format.cbSize));
+  DEBUG ((DEBUG_INFO, " Format->Format.Samples                = %d\n", Format->Format.Samples));
+  DEBUG ((DEBUG_INFO, " Format->Format.dwChannelMask          = 0x%x\n", Format->Format.dwChannelMask));
+  DEBUG ((DEBUG_INFO, " Format->Format.SubFormat              = %g\n", Format->Format.SubFormat));
+
+
+  DEBUG ((DEBUG_INFO, " Format->FormatConfiguration.CapabilitiesSize = %d B\n", Format->FormatConfiguration.CapabilitiesSize));
+  DEBUG ((DEBUG_VERBOSE, " Format->FormatConfiguration.Capabilities:"));
+  for (Index = 0; Index < (  Format->FormatConfiguration.CapabilitiesSize ) ; Index++) {
+    if (Index % 16 == 0) {
+      DEBUG ((DEBUG_VERBOSE, "\n"));
+    }
+    DEBUG ((DEBUG_VERBOSE, "0x%02x, ", Format->FormatConfiguration.Capabilities[Index]));
+  }
+  DEBUG ((DEBUG_VERBOSE, "\n"));
+}
+
+/**
+  Prints Device Information.
+
+  @param[in] *DeviceInfo       DeviceInfo to be printed
+
+  @retval None
+**/
+VOID
+NhltDeviceInfoDump (
+  IN CONST DEVICE_INFO          *DeviceInfo
+  )
+{
+  DEBUG ((DEBUG_INFO, "----------------------------- DEVICE INFO ----------------------------\n"));
+  DEBUG ((DEBUG_INFO, " DeviceInfo->DeviceId         = %a\n",   DeviceInfo->DeviceId));
+  DEBUG ((DEBUG_INFO, " DeviceInfo->DeviceInstanceId = 0x%x\n", DeviceInfo->DeviceInstanceId));
+  DEBUG ((DEBUG_INFO, " DeviceInfo->DevicePortId     = 0x%x\n", DeviceInfo->DevicePortId));
+}
+
+/**
+  Prints Endpoint configuration.
+
+  @param[in] *Endpoint     Endpoint to be printed
+
+  @retval None
+**/
+VOID
+NhltEndpointDump (
+  IN CONST ENDPOINT_DESCRIPTOR  *Endpoint
+  )
+{
+  UINT8 Index;
+  FORMATS_CONFIG *FormatsConfigs;
+  FORMAT_CONFIG  *Format;
+  DEVICES_INFO   *DevicesInfo;
+  DEVICE_INFO    *DeviceInfo;
+
+  DEBUG ((DEBUG_INFO, "------------------------------ ENDPOINT ------------------------------\n"));
+  DEBUG ((DEBUG_INFO, " Endpoint->DeviceDescriptorLength = %d B\n", Endpoint->EndpointDescriptorLength));
+  DEBUG ((DEBUG_INFO, " Endpoint->LinkType               = 0x%x\n", Endpoint->LinkType));
+  DEBUG ((DEBUG_INFO, " Endpoint->InstanceId             = 0x%x\n", Endpoint->InstanceId));
+  DEBUG ((DEBUG_INFO, " Endpoint->HwVendorId             = 0x%x\n", Endpoint->HwVendorId));
+  DEBUG ((DEBUG_INFO, " Endpoint->HwDeviceId             = 0x%x\n", Endpoint->HwDeviceId));
+  DEBUG ((DEBUG_INFO, " Endpoint->HwRevisionId           = 0x%x\n", Endpoint->HwRevisionId));
+  DEBUG ((DEBUG_INFO, " Endpoint->HwSubsystemId          = 0x%x\n", Endpoint->HwSubsystemId));
+  DEBUG ((DEBUG_INFO, " Endpoint->DeviceType             = 0x%x\n", Endpoint->DeviceType));
+  DEBUG ((DEBUG_INFO, " Endpoint->Direction              = 0x%x\n", Endpoint->Direction));
+  DEBUG ((DEBUG_INFO, " Endpoint->VirtualBusId           = 0x%x\n", Endpoint->VirtualBusId));
+
+  DEBUG ((DEBUG_INFO, " Endpoint->EndpointConfig.CapabilitiesSize = %d B\n", Endpoint->EndpointConfig.CapabilitiesSize));
+  DEBUG ((DEBUG_VERBOSE, " Endpoint->EndpointConfig.Capabilities:"));
+  for (Index = 0; Index < (Endpoint->EndpointConfig.CapabilitiesSize ) ; Index++) {
+    if (Index % 16 == 0) DEBUG ((DEBUG_VERBOSE, "\n"));
+    DEBUG ((DEBUG_VERBOSE, "0x%02x, ", Endpoint->EndpointConfig.Capabilities[Index]));
+  }
+
+  FormatsConfigs = GetNhltEndpointFormatsConfig (Endpoint);
+
+  DEBUG ((DEBUG_INFO, "\n"));
+  DEBUG ((DEBUG_INFO, " Endpoint->FormatsConfig.FormatsCount = %d\n", FormatsConfigs->FormatsCount));
+  for (Index = 0; Index < FormatsConfigs->FormatsCount; Index++) {
+    Format = GetNhltEndpointFormat (Endpoint, Index);
+    if (Format != NULL) {
+      NhltFormatDump (Format);
+    }
+  }
+
+  DevicesInfo = GetNhltEndpointDevicesInfo (Endpoint);
+  if (DevicesInfo != NULL) {
+    DEBUG ((DEBUG_INFO, "\n"));
+    DEBUG ((DEBUG_INFO, " Endpoint->DevicesInfo.DeviceInfoCount = %d\n", DevicesInfo->DeviceInfoCount));
+    for (Index = 0; Index < DevicesInfo->DeviceInfoCount; Index++) {
+      DeviceInfo = GetNhltEndpointDeviceInfo (Endpoint, Index);
+      if (DeviceInfo != NULL) {
+        NhltDeviceInfoDump (DeviceInfo);
+      }
+    }
+  }
+  DEBUG ((DEBUG_VERBOSE, "\n"));
+}
+
+/**
+  Prints OED (Offload Engine Driver) configuration.
+
+  @param[in] *OedConfig   OED to be printed
+
+  @retval None
+**/
+VOID
+NhltOedConfigDump (
+  IN CONST SPECIFIC_CONFIG      *OedConfig
+  )
+{
+  UINT8 Index;
+
+  DEBUG ((DEBUG_INFO, "-------------------------- OED CONFIGURATION -------------------------\n"));
+  DEBUG ((DEBUG_INFO, " OedConfig->CapabilitiesSize = %d B\n", OedConfig->CapabilitiesSize));
+  DEBUG ((DEBUG_VERBOSE, " OedConfig->Capabilities:"));
+  for (Index = 0; Index < (OedConfig->CapabilitiesSize) ; Index++) {
+    if (Index % 16 == 0) DEBUG ((DEBUG_VERBOSE, "\n"));
+    DEBUG ((DEBUG_VERBOSE, "0x%02x, ", OedConfig->Capabilities[Index]));
+  }
+
+  DEBUG ((DEBUG_VERBOSE, "\n"));
+}
+
+/**
+  Prints NHLT (Non HDA-Link Table) to be exposed via ACPI (aka. OED (Offload Engine Driver) Configuration Table).
+
+  @param[in] *NhltTable    The NHLT table to print
+
+  @retval None
+**/
+VOID
+NhltAcpiTableDump (
+  IN NHLT_ACPI_TABLE            *NhltTable
+  )
+{
+  DEBUG_CODE_BEGIN ();
+  UINT8 Index;
+
+  DEBUG ((DEBUG_INFO, "\n"));
+  DEBUG ((DEBUG_INFO, "--- NHLT ACPI Table Dump [OED (Offload Engine Driver) Configuration] ---\n"));
+
+  DEBUG ((DEBUG_INFO, "sizeof NHLT_ACPI_TABLE = %d B\n", sizeof (NHLT_ACPI_TABLE)));
+  DEBUG ((DEBUG_INFO, "sizeof EFI_ACPI_DESCRIPTION_HEADER = %d B\n", sizeof (EFI_ACPI_DESCRIPTION_HEADER)));
+  DEBUG ((DEBUG_INFO, "sizeof ENDPOINT_DESCRIPTOR = %d B\n", sizeof (ENDPOINT_DESCRIPTOR)));
+  DEBUG ((DEBUG_INFO, "sizeof SPECIFIC_CONFIG = %d B\n", sizeof (SPECIFIC_CONFIG)));
+  DEBUG ((DEBUG_INFO, "sizeof FORMATS_CONFIG = %d B\n", sizeof (FORMATS_CONFIG)));
+  DEBUG ((DEBUG_INFO, "sizeof FORMAT_CONFIG = %d B\n", sizeof (FORMAT_CONFIG)));
+  DEBUG ((DEBUG_INFO, "sizeof WAVEFORMATEXTENSIBLE = %d B\n", sizeof (WAVEFORMATEXTENSIBLE)));
+  DEBUG ((DEBUG_INFO, "sizeof DEVICES_INFO = %d B\n", sizeof (DEVICES_INFO)));
+  DEBUG ((DEBUG_INFO, "sizeof DEVICE_INFO = %d B\n", sizeof (DEVICE_INFO)));
+
+  DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.Signature       = 0x%08x\n", NhltTable->Header.Signature));
+  DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.Length          = 0x%08x\n", NhltTable->Header.Length));
+  DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.Revision        = 0x%02x\n", NhltTable->Header.Revision));
+  DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.Checksum        = 0x%02x\n", NhltTable->Header.Checksum));
+  DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.OemId           = %a\n",     NhltTable->Header.OemId));
+  DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.OemTableId      = 0x%lx\n",  NhltTable->Header.OemTableId));
+  DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.OemRevision     = 0x%08x\n", NhltTable->Header.OemRevision));
+  DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.CreatorId       = 0x%08x\n", NhltTable->Header.CreatorId));
+  DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.CreatorRevision = 0x%08x\n", NhltTable->Header.CreatorRevision));
+  DEBUG ((DEBUG_INFO, "\n"));
+
+  DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE EndpointCount = %d\n", NhltTable->EndpointCount));
+  for (Index = 0; Index < NhltTable->EndpointCount; Index++) {
+    NhltEndpointDump (GetNhltEndpoint (NhltTable, Index));
+  }
+
+  NhltOedConfigDump (GetNhltOedConfig (NhltTable));
+  DEBUG ((DEBUG_INFO, "----------------------------------------------------------------------\n"));
+
+  DEBUG_CODE_END ();
+}
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Hda/Library/DxeHdaNhltLib/DxeHdaNhltLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Hda/Library/DxeHdaNhltLib/DxeHdaNhltLib.inf
new file mode 100644
index 0000000000..a1574c3ab1
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Hda/Library/DxeHdaNhltLib/DxeHdaNhltLib.inf
@@ -0,0 +1,31 @@
+## @file
+# Component information file for HD Audio NHLT Library
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeHdaNhltLib
+FILE_GUID = DA915B7F-EE08-4C1D-B3D0-DE7C52AB155A
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = DxeHdaNhltLib
+
+[LibraryClasses]
+BaseLib
+DebugLib
+MemoryAllocationLib
+BaseMemoryLib
+PchInfoLib
+ConfigBlockLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Sources]
+DxeHdaNhltLib.c
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Hda/LibraryPrivate/DxeHdaPolicyLib/DxeHdaPolicyLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Hda/LibraryPrivate/DxeHdaPolicyLib/DxeHdaPolicyLib.c
new file mode 100644
index 0000000000..30843fab39
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Hda/LibraryPrivate/DxeHdaPolicyLib/DxeHdaPolicyLib.c
@@ -0,0 +1,92 @@
+/** @file
+  This file provides services for Hda policy function
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/SiConfigBlockLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Protocol/PchPolicy.h>
+#include <HdAudioConfig.h>
+
+/**
+  Print HDAUDIO_DXE_CONFIG and serial out.
+
+  @param[in] PchPolicy            Pointer to a PCH_POLICY_PROTOCOL
+**/
+VOID
+HdaDxePrintConfig (
+  IN PCH_POLICY_PROTOCOL    *PchPolicy
+  )
+{
+  EFI_STATUS            Status;
+  HDAUDIO_DXE_CONFIG    *HdaDxeConfig;
+  UINT32                Index;
+
+  Status = GetConfigBlock ((VOID *) PchPolicy, &gHdAudioDxeConfigGuid, (VOID *) &HdaDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "------------------ HD-Audio DXE Config ------------------\n"));
+
+  for (Index = 0; Index < PCH_MAX_HDA_SNDW_LINK_NUM; Index++) {
+    DEBUG ((DEBUG_INFO, " SNDW%d AutonomousClockStop  : %d\n", Index, HdaDxeConfig->SndwConfig[Index].AutonomousClockStop));
+    DEBUG ((DEBUG_INFO, " SNDW%d DODS                 : %d\n", Index, HdaDxeConfig->SndwConfig[Index].DataOnDelaySelect));
+    DEBUG ((DEBUG_INFO, " SNDW%d DOAS                 : %d\n", Index, HdaDxeConfig->SndwConfig[Index].DataOnActiveIntervalSelect));
+  }
+  DEBUG ((DEBUG_INFO, " DSP Feature Mask              : 0x%x\n", HdaDxeConfig->DspFeatureMask));
+}
+
+/**
+  Load Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+HdaDxeLoadConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  HDAUDIO_DXE_CONFIG  *HdAudioDxeConfig;
+  HdAudioDxeConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "HdaDxeConfig->Header.GuidHob.Name = %g\n", &HdAudioDxeConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "HdaDxeConfig->Header.GuidHob.Header.HobLength = 0x%x\n", HdAudioDxeConfig->Header.GuidHob.Header.HobLength));
+}
+
+STATIC COMPONENT_BLOCK_ENTRY  mHdaBlocks = {
+  &gHdAudioDxeConfigGuid,
+  sizeof (HDAUDIO_DXE_CONFIG),
+  HDAUDIO_DXE_CONFIG_REVISION,
+  HdaDxeLoadConfigDefault
+};
+
+/**
+  Get Hda config block table size.
+
+  @retval      Size of config block
+**/
+UINT16
+HdaDxeGetConfigBlockTotalSize (
+  VOID
+  )
+{
+  return mHdaBlocks.Size;
+}
+
+/**
+  Add Hda ConfigBlock.
+
+  @param[in] ConfigBlockTableAddress    The pointer to config block table
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+HdaDxeAddConfigBlock (
+  IN VOID           *ConfigBlockTableAddress
+  )
+{
+  return AddComponentConfigBlocks (ConfigBlockTableAddress, &mHdaBlocks, 1);
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Hda/LibraryPrivate/DxeHdaPolicyLib/DxeHdaPolicyLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Hda/LibraryPrivate/DxeHdaPolicyLib/DxeHdaPolicyLib.inf
new file mode 100644
index 0000000000..758499b95e
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Hda/LibraryPrivate/DxeHdaPolicyLib/DxeHdaPolicyLib.inf
@@ -0,0 +1,31 @@
+## @file
+# Component description file for the Hda policy library
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeHdaPolicyLib
+FILE_GUID = B053EFE4-0868-4510-A71D-96A85CD16C77
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = DxeHdaPolicyLib
+
+[LibraryClasses]
+DebugLib
+ConfigBlockLib
+SiConfigBlockLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Sources]
+DxeHdaPolicyLib.c
+
+[Guids]
+gHdAudioDxeConfigGuid  ## CONSUMES
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 20/40] TigerlakeSiliconPkg/IpBlock: Add HostBridge component
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (17 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 19/40] TigerlakeSiliconPkg/IpBlock: Add Hda component Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 21/40] TigerlakeSiliconPkg/IpBlock: Add P2sb component Heng Luo
                   ` (19 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * IpBlock/HostBridge/IncludePrivate

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/HostBridge/IncludePrivate/HostBridgeDataHob.h | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/HostBridge/IncludePrivate/HostBridgeDataHob.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/HostBridge/IncludePrivate/HostBridgeDataHob.h
new file mode 100644
index 0000000000..41e92da4df
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/HostBridge/IncludePrivate/HostBridgeDataHob.h
@@ -0,0 +1,25 @@
+/** @file
+  The GUID definition for Host Bridge Data Hob
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _HOST_BRIDGE_DATA_HOB_H_
+#define _HOST_BRIDGE_DATA_HOB_H_
+
+#include <Base.h>
+
+extern EFI_GUID gHostBridgeDataHobGuid;
+#pragma pack (push,1)
+
+///
+/// Host Bridge Data Hob
+///
+typedef struct {
+  EFI_HOB_GUID_TYPE        EfiHobGuidType;                       ///< GUID Hob type structure for gSaDataHobGuid
+  UINT8                    EnableAbove4GBMmio;                   ///< 0=Disable above 4GB MMIO resource support, 1=Enable above 4GB MMIO resource support
+  BOOLEAN                  SkipPamLock;                          ///< 0=All PAM registers will be locked in System Agent code, 1=Do not lock PAM registers in System Agent code.
+  UINT8                    Rsvd1[2];                             ///< Reserved for future use
+} HOST_BRIDGE_DATA_HOB;
+#pragma pack (pop)
+#endif
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 21/40] TigerlakeSiliconPkg/IpBlock: Add P2sb component
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (18 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 20/40] TigerlakeSiliconPkg/IpBlock: Add HostBridge component Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 22/40] TigerlakeSiliconPkg/IpBlock: Add PchDmi component Heng Luo
                   ` (18 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * IpBlock/P2sb/IncludePrivate
  * IpBlock/P2sb/Library
  * IpBlock/P2sb/LibraryPrivate

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/IncludePrivate/Library/PchSbiAccessLib.h                             | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/IncludePrivate/Register/P2sbRegs.h                                   |  65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuRegbarAccessLib/CpuRegbarAccessLib.c             | 494 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuRegbarAccessLib/PeiDxeSmmCpuRegbarAccessLib.inf  |  35 +++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmPchPcrLib/PchPcrLib.c                               | 313 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmPchPcrLib/PeiDxeSmmPchPcrLib.inf                    |  35 +++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmPchSbiAccessLib/PchSbiAccessLib.c            | 253 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmPchSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf |  36 ++++++++++++++++++++++++++++++++++++
 8 files changed, 1343 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/IncludePrivate/Library/PchSbiAccessLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/IncludePrivate/Library/PchSbiAccessLib.h
new file mode 100644
index 0000000000..3fab933bbd
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/IncludePrivate/Library/PchSbiAccessLib.h
@@ -0,0 +1,112 @@
+/** @file
+  Header file for PchSbiAccessLib.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_SBI_ACCESS_LIB_H_
+#define _PCH_SBI_ACCESS_LIB_H_
+
+#include <Library/PchPcrLib.h>
+
+/**
+  PCH SBI opcode definitions
+**/
+typedef enum {
+  MemoryRead             = 0x0,
+  MemoryWrite            = 0x1,
+  PciConfigRead          = 0x4,
+  PciConfigWrite         = 0x5,
+  PrivateControlRead     = 0x6,
+  PrivateControlWrite    = 0x7,
+  GpioLockUnlock         = 0x13
+} PCH_SBI_OPCODE;
+
+/**
+  PCH SBI response status definitions
+**/
+typedef enum {
+  SBI_SUCCESSFUL          = 0,
+  SBI_UNSUCCESSFUL        = 1,
+  SBI_POWERDOWN           = 2,
+  SBI_MIXED               = 3,
+  SBI_INVALID_RESPONSE
+} PCH_SBI_RESPONSE;
+
+/**
+  Execute PCH SBI message
+  Take care of that there is no lock protection when using SBI programming in both POST time and SMI.
+  It will clash with POST time SBI programming when SMI happen.
+  Programmer MUST do the save and restore opration while using the PchSbiExecution inside SMI
+  to prevent from racing condition.
+  This function will reveal P2SB and hide P2SB if it's originally hidden. If more than one SBI access
+  needed, it's better to unhide the P2SB before calling and hide it back after done.
+
+  When the return value is "EFI_SUCCESS", the "Response" do not need to be checked as it would have been
+  SBI_SUCCESS. If the return value is "EFI_DEVICE_ERROR", then this would provide additional information
+  when needed.
+
+  @param[in] Pid                        Port ID of the SBI message
+  @param[in] Offset                     Offset of the SBI message
+  @param[in] Opcode                     Opcode
+  @param[in] Posted                     Posted message
+  @param[in, out] Data32                Read/Write data
+  @param[out] Response                  Response
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_DEVICE_ERROR              Transaction fail
+  @retval EFI_INVALID_PARAMETER         Invalid parameter
+  @retval EFI_TIMEOUT                   Timeout while waiting for response
+**/
+EFI_STATUS
+PchSbiExecution (
+  IN     PCH_SBI_PID                    Pid,
+  IN     UINT64                         Offset,
+  IN     PCH_SBI_OPCODE                 Opcode,
+  IN     BOOLEAN                        Posted,
+  IN OUT UINT32                         *Data32,
+  OUT    UINT8                          *Response
+  );
+
+/**
+  Full function for executing PCH SBI message
+  Take care of that there is no lock protection when using SBI programming in both POST time and SMI.
+  It will clash with POST time SBI programming when SMI happen.
+  Programmer MUST do the save and restore opration while using the PchSbiExecution inside SMI
+  to prevent from racing condition.
+  This function will reveal P2SB and hide P2SB if it's originally hidden. If more than one SBI access
+  needed, it's better to unhide the P2SB before calling and hide it back after done.
+
+  When the return value is "EFI_SUCCESS", the "Response" do not need to be checked as it would have been
+  SBI_SUCCESS. If the return value is "EFI_DEVICE_ERROR", then this would provide additional information
+  when needed.
+
+  @param[in] Pid                        Port ID of the SBI message
+  @param[in] Offset                     Offset of the SBI message
+  @param[in] Opcode                     Opcode
+  @param[in] Posted                     Posted message
+  @param[in] Fbe                        First byte enable
+  @param[in] Bar                        Bar
+  @param[in] Fid                        Function ID
+  @param[in, out] Data32                Read/Write data
+  @param[out] Response                  Response
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_DEVICE_ERROR              Transaction fail
+  @retval EFI_INVALID_PARAMETER         Invalid parameter
+  @retval EFI_TIMEOUT                   Timeout while waiting for response
+**/
+EFI_STATUS
+PchSbiExecutionEx (
+  IN     PCH_SBI_PID                    Pid,
+  IN     UINT64                         Offset,
+  IN     PCH_SBI_OPCODE                 Opcode,
+  IN     BOOLEAN                        Posted,
+  IN     UINT16                         Fbe,
+  IN     UINT16                         Bar,
+  IN     UINT16                         Fid,
+  IN OUT UINT32                         *Data32,
+  OUT    UINT8                          *Response
+  );
+
+#endif // _PCH_SBI_ACCESS_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/IncludePrivate/Register/P2sbRegs.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/IncludePrivate/Register/P2sbRegs.h
new file mode 100644
index 0000000000..44c71af719
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/IncludePrivate/Register/P2sbRegs.h
@@ -0,0 +1,65 @@
+/** @file
+  Register names for PCH P2SB device
+
+  Conventions:
+
+  - Register definition format:
+    Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpace_RegisterName
+  - Prefix:
+    Definitions beginning with "R_" are registers
+    Definitions beginning with "B_" are bits within registers
+    Definitions beginning with "V_" are meaningful values within the bits
+    Definitions beginning with "S_" are register size
+    Definitions beginning with "N_" are the bit position
+  - [GenerationName]:
+    Three letter acronym of the generation is used (e.g. SKL,KBL,CNL etc.).
+    Register name without GenerationName applies to all generations.
+  - [ComponentName]:
+    This field indicates the component name that the register belongs to (e.g. PCH, SA etc.)
+    Register name without ComponentName applies to all components.
+    Register that is specific to -LP denoted by "_PCH_LP_" in component name.
+  - SubsystemName:
+    This field indicates the subsystem name of the component that the register belongs to
+    (e.g. PCIE, USB, SATA, GPIO, PMC etc.).
+  - RegisterSpace:
+    MEM - MMIO space register of subsystem.
+    IO  - IO space register of subsystem.
+    PCR - Private configuration register of subsystem.
+    CFG - PCI configuration space register of subsystem.
+  - RegisterName:
+    Full register name.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _P2SB_REGS_H_
+#define _P2SB_REGS_H_
+
+//
+// PCI to P2SB Bridge Registers
+//
+
+#define R_IO_APIC_MEM_INDEX_OFFSET                 0x00
+#define R_IO_APIC_MEM_DATA_OFFSET                  0x10
+#define V_P2SB_CFG_IBDF_BUS                        0
+#define V_P2SB_CFG_IBDF_DEV                        30
+#define V_P2SB_CFG_IBDF_FUNC                       7
+#define V_P2SB_CFG_HBDF_BUS                        0
+#define V_P2SB_CFG_HBDF_DEV                        30
+#define V_P2SB_CFG_HBDF_FUNC                       6
+
+//
+// Definition for SBI
+//
+#define R_P2SB_CFG_SBIADDR                         0xD0
+#define R_P2SB_CFG_SBIDATA                         0xD4
+#define R_P2SB_CFG_SBISTAT                         0xD8
+#define B_P2SB_CFG_SBISTAT_OPCODE                  0xFF00
+#define B_P2SB_CFG_SBISTAT_POSTED                  BIT7
+#define B_P2SB_CFG_SBISTAT_RESPONSE                0x0006
+#define N_P2SB_CFG_SBISTAT_RESPONSE                1
+#define B_P2SB_CFG_SBISTAT_INITRDY                 BIT0
+#define R_P2SB_CFG_SBIRID                          0xDA
+#define R_P2SB_CFG_SBIEXTADDR                      0xDC
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuRegbarAccessLib/CpuRegbarAccessLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuRegbarAccessLib/CpuRegbarAccessLib.c
new file mode 100644
index 0000000000..9d8851ac37
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuRegbarAccessLib/CpuRegbarAccessLib.c
@@ -0,0 +1,494 @@
+/** @file
+  CPU REGBAR ACCESS library.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/CpuRegbarAccessLib.h>
+
+/**
+  Definition for REGBAR address
+  The REGBAR address is used for the CPU IP's SB register access
+**/
+#define CPU_REGBAR_ADDRESS(Pid, Offset)    (PcdGet32(PcdRegBarBaseAddress) | ((UINT8)(Pid) << 16) | (UINT16)(Offset))
+
+/**
+  Read REGBAR register.
+  It returns REGBAR register and size in 8bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid   CPU SB Device Port ID
+  @param[in]  Offset           Register offset of this Port ID
+
+  @retval     UINT64           REGBAR register value.
+**/
+UINT64
+CpuRegbarRead64 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset
+  )
+{
+  UINT8    Pid;
+
+  Pid = CpuSbDevicePid;
+  if (Pid != INVALID_PID)
+    return ((UINT64) MmioRead32 (CPU_REGBAR_ADDRESS (Pid, Offset)) + LShiftU64 ((UINT64) MmioRead32 (CPU_REGBAR_ADDRESS (Pid, Offset+4)), 32));
+  else
+    return INVALID_DATA_64;
+}
+
+
+/**
+  Read REGBAR register.
+  It returns REGBAR register and size in 4bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid   CPU SB Device Port ID
+  @param[in]  Offset              Register offset of this Port ID
+
+  @retval     UINT32           REGBAR register value.
+**/
+UINT32
+CpuRegbarRead32 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset
+  )
+{
+  UINT8    Pid;
+
+  Pid = CpuSbDevicePid;
+  if (Pid != INVALID_PID)
+    return MmioRead32 (CPU_REGBAR_ADDRESS (Pid, Offset));
+  else
+    return INVALID_DATA_32;
+}
+
+/**
+  Read REGBAR register.
+  It returns REGBAR register and size in 2bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid   CPU SB Device Port ID
+  @param[in]  Offset           Register offset of this Port ID
+
+  @retval     UINT16           REGBAR register value.
+**/
+UINT16
+CpuRegbarRead16 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset
+  )
+{
+  UINT16   DwOffset;
+  UINT32   Data32;
+  UINT16   Data16;
+
+  Data16 = 0;
+  Data32 = 0;
+  DwOffset = 0;
+
+  if (CpuSbDevicePid == INVALID_PID) {
+    return INVALID_DATA_16;
+  }
+  switch (Offset & 0x0003) {
+    case 0:
+      DwOffset = Offset;
+      break;
+    case 2:
+      DwOffset = Offset - 0x2;
+      break;
+  }
+  Data32 = MmioRead32 (CPU_REGBAR_ADDRESS (CpuSbDevicePid, DwOffset));
+  switch (Offset & 0x0003) {
+    case 0:
+      Data16 = (UINT16) Data32;
+      break;
+    case 2:
+      Data16 = (UINT16) (Data32 >> 16);
+      break;
+  }
+  return Data16;
+}
+
+/**
+  Read REGBAR register.
+  It returns REGBAR register and size in 1bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid   CPU SB Device Port ID
+  @param[in]  Offset           Register offset of this Port ID
+
+  @retval     UINT8            REGBAR regsiter value
+**/
+UINT8
+CpuRegbarRead8 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset
+  )
+{
+  UINT16   DwOffset;
+  UINT32   Data32;
+  UINT8    Data8;
+
+  DwOffset = 0;
+  Data32 = 0;
+  Data8 = 0;
+
+  if (CpuSbDevicePid == INVALID_PID)
+    return INVALID_DATA_8;
+  switch (Offset & 0x0003) {
+    case 0:
+      DwOffset = Offset;
+      break;
+    case 1:
+      DwOffset = Offset - 0x1;
+      break;
+    case 2:
+      DwOffset = Offset - 0x2;
+      break;
+    case 3:
+      DwOffset = Offset - 0x3;
+      break;
+  }
+  Data32 = MmioRead32 (CPU_REGBAR_ADDRESS (CpuSbDevicePid, DwOffset));
+  switch (Offset & 0x0003) {
+    case 0:
+      Data8 = (UINT8) Data32;
+      break;
+    case 1:
+      Data8 = (UINT8) (Data32 >> 8);
+      break;
+    case 2:
+      Data8 = (UINT8) (Data32 >> 16);
+      break;
+    case 3:
+      Data8 = (UINT8) (Data32 >> 24);
+      break;
+  }
+  return Data8;
+}
+
+
+/**
+  Write REGBAR register.
+  It programs REGBAR register and size in 8bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid   CPU SB Device Port ID
+  @param[in]  Offset           Register offset of Port ID.
+  @param[in]  Data             Input Data. Must be the same size as Size parameter.
+
+  @retval     UINT64           Value written to register
+**/
+UINT64
+CpuRegbarWrite64 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT64                            Data
+  )
+{
+  UINT8       Pid;
+
+  Pid = CpuSbDevicePid;
+  if (Pid != INVALID_PID) {
+    MmioWrite32 (CPU_REGBAR_ADDRESS (Pid, Offset) + 4, (UINT32) RShiftU64 (Data, 32));
+    MmioWrite32 (CPU_REGBAR_ADDRESS (Pid, Offset), (UINT32) Data);
+    return Data;
+  }
+  else
+    return INVALID_DATA_64;
+}
+
+
+/**
+  Write REGBAR register.
+  It programs REGBAR register and size in 4bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid   CPU SB Device Port ID
+  @param[in]  Offset           Register offset of Port ID.
+  @param[in]  Data             Input Data. Must be the same size as Size parameter.
+
+  @retval     UINT32           Value written to register
+**/
+UINT32
+CpuRegbarWrite32 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT32                            Data
+  )
+{
+  UINT8    Pid;
+
+  Pid = CpuSbDevicePid;
+  if (Pid != INVALID_PID)
+    return MmioWrite32 (CPU_REGBAR_ADDRESS (Pid, Offset), Data);
+  else
+    return INVALID_DATA_32;
+}
+
+/**
+  Write REGBAR register.
+  It programs REGBAR register and size in 2bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid   CPU SB Device Port ID
+  @param[in]  Offset           Register offset of Port ID.
+  @param[in]  Data             Input Data. Must be the same size as Size parameter.
+
+  @retval     UINT16           Value written to register
+**/
+UINT16
+CpuRegbarWrite16 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT16                            Data
+  )
+{
+  UINT8    Pid;
+
+  Pid = CpuSbDevicePid;
+  if (Pid != INVALID_PID)
+    return MmioWrite16 (CPU_REGBAR_ADDRESS (Pid, Offset), Data);
+  else
+    return INVALID_DATA_16;
+}
+
+/**
+  Write REGBAR register.
+  It programs REGBAR register and size in 1bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid   CPU SB Device Port ID
+  @param[in]  Offset           Register offset of Port ID.
+  @param[in]  Data             Input Data. Must be the same size as Size parameter.
+
+  @retval     UINT8            Value written to register
+**/
+UINT8
+CpuRegbarWrite8 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT8                             Data
+  )
+{
+  UINT8    Pid;
+
+  Pid = CpuSbDevicePid;
+  if (Pid != INVALID_PID)
+    return MmioWrite8 (CPU_REGBAR_ADDRESS (Pid, Offset), Data);
+  else
+    return INVALID_DATA_8;
+}
+
+/**
+  Write REGBAR register.
+  It programs REGBAR register and size in 4bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid   CPU SB Device Port ID
+  @param[in]  Offset           Register offset of Port ID.
+  @param[in]  OrData           OR Data. Must be the same size as Size parameter.
+
+  @retval     UINT32           Value written to register
+
+**/
+UINT32
+CpuRegbarOr32 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT32                            OrData
+  )
+{
+  return CpuRegbarWrite32 (CpuSbDevicePid, Offset, CpuRegbarRead32(CpuSbDevicePid, Offset) | OrData);
+}
+
+/**
+  Write REGBAR register.
+  It programs REGBAR register and size in 2bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid   CPU SB Device Port ID
+  @param[in]  Offset           Register offset of Port ID.
+  @param[in]  OrData           OR Data. Must be the same size as Size parameter.
+
+  @retval     UINT16           Value written to register
+
+**/
+UINT16
+CpuRegbarOr16 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT16                            OrData
+  )
+{
+  return CpuRegbarWrite16 (CpuSbDevicePid, Offset, CpuRegbarRead16(CpuSbDevicePid, Offset) | OrData);
+}
+
+/**
+  Write REGBAR register.
+  It programs REGBAR register and size in 1bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid   CPU SB Device Port ID
+  @param[in]  Offset           Register offset of Port ID.
+  @param[in]  OrData           OR Data. Must be the same size as Size parameter.
+
+  @retval     UINT8            Value written to register
+
+**/
+UINT8
+CpuRegbarOr8(
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT8                             OrData
+  )
+{
+  return CpuRegbarWrite8 (CpuSbDevicePid, Offset, CpuRegbarRead8(CpuSbDevicePid, Offset) | OrData);
+}
+
+/**
+  Performs a bitwise AND of a 32-bit data.
+  It programs REGBAR register and size in 4bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevice      CPU SB Device
+  @param[in]  Offset           Register offset of Port ID.
+  @param[in]  AndData          And Data. Must be the same size as Size parameter.
+
+  @retval     UINT32           Value written to register
+
+**/
+UINT32
+CpuRegbarAnd32 (
+  IN  CPU_SB_DEVICE_PID                     CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT32                            AndData
+  )
+{
+  return CpuRegbarWrite32 (CpuSbDevicePid, Offset, CpuRegbarRead32 (CpuSbDevicePid, Offset) & AndData);
+}
+
+/**
+  Performs a bitwise AND of a 16-bit data.
+  It programs REGBAR register and size in 2bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevice      CPU SB Device
+  @param[in]  Offset           Register offset of Port ID.
+  @param[in]  AndData          And Data. Must be the same size as Size parameter.
+
+  @retval     UINT16           Value written to register
+
+**/
+UINT16
+CpuRegbarAnd16 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT16                            AndData
+  )
+{
+  return CpuRegbarWrite16 (CpuSbDevicePid, Offset, CpuRegbarRead16 (CpuSbDevicePid, Offset) & AndData);
+}
+
+/**
+Performs a bitwise AND of a 8-bit data.
+It programs REGBAR register and size in 1byte.
+The Offset should not exceed 0xFFFF and must be aligned with size.
+
+@param[in]  CpuSbDevice      CPU SB Device
+@param[in]  Offset           Register offset of Port ID.
+@param[in]  AndData          And Data. Must be the same size as Size parameter.
+
+@retval     UINT8           Value written to register
+
+**/
+UINT8
+CpuRegbarAnd8 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT8                             AndData
+  )
+{
+  return CpuRegbarWrite8 (CpuSbDevicePid, Offset, CpuRegbarRead8 (CpuSbDevicePid, Offset) & AndData);
+}
+
+/**
+  Write REGBAR register.
+  It programs REGBAR register and size in 4bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid   CPU SB Device Port ID
+  @param[in]  Offset           Register offset of Port ID.
+  @param[in]  AndData          AND Data. Must be the same size as Size parameter.
+  @param[in]  OrData           OR Data. Must be the same size as Size parameter.
+
+  @retval     UINT32           Value written to register
+
+**/
+UINT32
+CpuRegbarAndThenOr32 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT32                            AndData,
+  IN  UINT32                            OrData
+  )
+{
+  return CpuRegbarWrite32 (CpuSbDevicePid, Offset, (CpuRegbarRead32 (CpuSbDevicePid, Offset) & AndData) | OrData);
+}
+
+/**
+  Write REGBAR register.
+  It programs REGBAR register and size in 2bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid   CPU SB Device Port ID
+  @param[in]  Offset           Register offset of Port ID.
+  @param[in]  AndData          AND Data. Must be the same size as Size parameter.
+  @param[in]  OrData           OR Data. Must be the same size as Size parameter.
+
+  @retval     UINT16           Value written to register
+
+**/
+UINT16
+CpuRegbarAndThenOr16 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT16                            AndData,
+  IN  UINT16                            OrData
+  )
+{
+  return CpuRegbarWrite16 (CpuSbDevicePid, Offset, (CpuRegbarRead16 (CpuSbDevicePid, Offset) & AndData) | OrData);
+}
+
+/**
+  Write REGBAR register.
+  It programs REGBAR register and size in 1bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  CpuSbDevicePid   CPU SB Device Port ID
+  @param[in]  Offset           Register offset of Port ID.
+  @param[in]  AndData          AND Data. Must be the same size as Size parameter.
+  @param[in]  OrData           OR Data. Must be the same size as Size parameter.
+
+  @retval     UINT8            Value written to register
+
+**/
+UINT8
+CpuRegbarAndThenOr8 (
+  IN  CPU_SB_DEVICE_PID                 CpuSbDevicePid,
+  IN  UINT16                            Offset,
+  IN  UINT8                             AndData,
+  IN  UINT8                             OrData
+  )
+{
+  return CpuRegbarWrite8 (CpuSbDevicePid, Offset, (CpuRegbarRead8 (CpuSbDevicePid, Offset) & AndData) | OrData);
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuRegbarAccessLib/PeiDxeSmmCpuRegbarAccessLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuRegbarAccessLib/PeiDxeSmmCpuRegbarAccessLib.inf
new file mode 100644
index 0000000000..596543f34f
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmCpuRegbarAccessLib/PeiDxeSmmCpuRegbarAccessLib.inf
@@ -0,0 +1,35 @@
+## @file
+# CPU REGBAR ACCESS Library.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmCpuRegbarAccessLib
+FILE_GUID = CA92B911-528D-4FBB-9A5A-7BC22AA1A6D0
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = CpuRegbarAccessLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+gSiPkgTokenSpaceGuid.PcdRegBarBaseAddress
+
+[Sources]
+CpuRegbarAccessLib.c
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmPchPcrLib/PchPcrLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmPchPcrLib/PchPcrLib.c
new file mode 100644
index 0000000000..c4f3740c86
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmPchPcrLib/PchPcrLib.c
@@ -0,0 +1,313 @@
+/** @file
+  PCH PCR library.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchPcrLib.h>
+#include <Register/PchPcrRegs.h>
+
+#ifndef MDEPKG_NDEBUG
+/**
+  Checks if the offset is valid for a given memory access width. Offset must align to width size.
+
+  @param[in]  Offset  Offset of a register
+  @param[in]  Size    Size of memory access in bytes
+
+  @retval FALSE  Offset is not valid for a given memory access
+  @retval TRUE   Offset is valid
+**/
+STATIC
+BOOLEAN
+PchIsPcrOffsetValid (
+  IN UINT32  Offset,
+  IN UINTN   Size
+  )
+{
+  if (!IsP2sb20bPcrSupported ()) {
+    if (((Offset & (Size - 1)) != 0) || (Offset > 0xFFFF)) {
+      DEBUG ((DEBUG_ERROR, "PCR offset error. Invalid Offset: %x Size: %x", Offset, Size));
+      return FALSE;
+    } else {
+      return TRUE;
+    }
+  } else {
+    if (((Offset & (Size - 1)) != 0) || (Offset > 0xFFFFF)) {
+      DEBUG ((DEBUG_ERROR, "PCR offset error. Invalid Offset: %x Size: %x", Offset, Size));
+      return FALSE;
+    } else {
+      return TRUE;
+    }
+  }
+}
+#endif
+
+/**
+  Read PCR register.
+  It returns PCR register and size in 4bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  Pid      Port ID
+  @param[in]  Offset   Register offset of this Port ID
+
+  @retval UINT32       PCR register value.
+**/
+UINT32
+PchPcrRead32 (
+  IN  PCH_SBI_PID                       Pid,
+  IN  UINT32                            Offset
+  )
+{
+#ifndef MDEPKG_NDEBUG
+  ASSERT (PchIsPcrOffsetValid (Offset, 4));
+#endif
+  return MmioRead32 (PCH_PCR_ADDRESS (Pid, Offset));
+}
+
+/**
+  Read PCR register.
+  It returns PCR register and size in 2bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  Pid      Port ID
+  @param[in]  Offset   Register offset of this Port ID
+
+  @retval UINT16       PCR register value.
+**/
+UINT16
+PchPcrRead16 (
+  IN  PCH_SBI_PID                       Pid,
+  IN  UINT32                            Offset
+  )
+{
+#ifndef MDEPKG_NDEBUG
+  ASSERT (PchIsPcrOffsetValid (Offset, 2));
+#endif
+  return MmioRead16 (PCH_PCR_ADDRESS (Pid, Offset));
+}
+
+/**
+  Read PCR register.
+  It returns PCR register and size in 1bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  Pid      Port ID
+  @param[in]  Offset   Register offset of this Port ID
+
+  @retval UINT8        PCR register value
+**/
+UINT8
+PchPcrRead8 (
+  IN  PCH_SBI_PID                       Pid,
+  IN  UINT32                            Offset
+  )
+{
+  return MmioRead8 (PCH_PCR_ADDRESS (Pid, Offset));
+}
+
+/**
+  Write PCR register.
+  It programs PCR register and size in 4bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  Pid      Port ID
+  @param[in]  Offset   Register offset of Port ID.
+  @param[in]  Data     Input Data. Must be the same size as Size parameter.
+
+  @retval UINT32       Value written to register
+**/
+UINT32
+PchPcrWrite32 (
+  IN  PCH_SBI_PID                       Pid,
+  IN  UINT32                            Offset,
+  IN  UINT32                            Data
+  )
+{
+#ifndef MDEPKG_NDEBUG
+  ASSERT (PchIsPcrOffsetValid (Offset, 4));
+#endif
+  MmioWrite32 (PCH_PCR_ADDRESS (Pid, Offset), Data);
+
+  return Data;
+
+}
+
+/**
+  Write PCR register.
+  It programs PCR register and size in 2bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  Pid      Port ID
+  @param[in]  Offset   Register offset of Port ID.
+  @param[in]  Data     Input Data. Must be the same size as Size parameter.
+
+  @retval  UINT16      Value written to register
+**/
+UINT16
+PchPcrWrite16 (
+  IN  PCH_SBI_PID                       Pid,
+  IN  UINT32                            Offset,
+  IN  UINT16                            Data
+  )
+{
+#ifndef MDEPKG_NDEBUG
+  ASSERT (PchIsPcrOffsetValid (Offset, 2));
+#endif
+  MmioWrite16 (PCH_PCR_ADDRESS (Pid, Offset), Data);
+
+  return Data;
+}
+
+/**
+  Write PCR register.
+  It programs PCR register and size in 1bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  Pid      Port ID
+  @param[in]  Offset   Register offset of Port ID.
+  @param[in]  Data     Input Data. Must be the same size as Size parameter.
+
+  @retval  UINT8       Value written to register
+**/
+UINT8
+PchPcrWrite8 (
+  IN  PCH_SBI_PID                       Pid,
+  IN  UINT32                            Offset,
+  IN  UINT8                             Data
+  )
+{
+
+  MmioWrite8 (PCH_PCR_ADDRESS (Pid, Offset), Data);
+
+  return Data;
+}
+
+/**
+  Write PCR register.
+  It programs PCR register and size in 4bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  Pid      Port ID
+  @param[in]  Offset   Register offset of Port ID.
+  @param[in]  AndData  AND Data. Must be the same size as Size parameter.
+  @param[in]  OrData   OR Data. Must be the same size as Size parameter.
+
+  @retval  UINT32      Value written to register
+
+**/
+UINT32
+PchPcrAndThenOr32 (
+  IN  PCH_SBI_PID                       Pid,
+  IN  UINT32                            Offset,
+  IN  UINT32                            AndData,
+  IN  UINT32                            OrData
+  )
+{
+  return PchPcrWrite32 (Pid, Offset, (PchPcrRead32 (Pid, Offset) & AndData) | OrData);
+}
+
+/**
+  Write PCR register and read back.
+  The read back ensures the PCR cycle is completed before next operation.
+  It programs PCR register and size in 4bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  Pid      Port ID
+  @param[in]  Offset   Register offset of Port ID.
+  @param[in]  AndData  AND Data. Must be the same size as Size parameter.
+  @param[in]  OrData   OR Data. Must be the same size as Size parameter.
+
+  @retval  UINT32      Value read back from the register
+**/
+UINT32
+PchPcrAndThenOr32WithReadback (
+  IN  PCH_SBI_PID                       Pid,
+  IN  UINT32                            Offset,
+  IN  UINT32                            AndData,
+  IN  UINT32                            OrData
+  )
+{
+  PchPcrWrite32 (Pid, Offset, (PchPcrRead32 (Pid, Offset) & AndData) | OrData);
+  return PchPcrRead32 (Pid, Offset);
+}
+
+/**
+  Write PCR register.
+  It programs PCR register and size in 2bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  Pid      Port ID
+  @param[in]  Offset   Register offset of Port ID.
+  @param[in]  AndData  AND Data. Must be the same size as Size parameter.
+  @param[in]  OrData   OR Data. Must be the same size as Size parameter.
+
+  @retval UINT16       Value written to register
+
+**/
+UINT16
+PchPcrAndThenOr16 (
+  IN  PCH_SBI_PID                       Pid,
+  IN  UINT32                            Offset,
+  IN  UINT16                            AndData,
+  IN  UINT16                            OrData
+  )
+{
+  return PchPcrWrite16 (Pid, Offset, (PchPcrRead16 (Pid, Offset) & AndData) | OrData);
+}
+
+/**
+  Write PCR register.
+  It programs PCR register and size in 1bytes.
+  The Offset should not exceed 0xFFFF and must be aligned with size.
+
+  @param[in]  Pid      Port ID
+  @param[in]  Offset   Register offset of Port ID.
+  @param[in]  AndData  AND Data. Must be the same size as Size parameter.
+  @param[in]  OrData   OR Data. Must be the same size as Size parameter.
+
+  @retval  UINT8       Value written to register
+
+**/
+UINT8
+PchPcrAndThenOr8 (
+  IN  PCH_SBI_PID                       Pid,
+  IN  UINT32                            Offset,
+  IN  UINT8                             AndData,
+  IN  UINT8                             OrData
+  )
+{
+  return PchPcrWrite8 (Pid, Offset, (PchPcrRead8 (Pid, Offset) & AndData) | OrData);
+}
+
+/**
+  Get PCH IP PID number
+
+  @param[in]  IpEnum   PCH IP in PCH_IP_PID_ENUM
+
+  @retval     0        PID of this IP is not supported
+              !0       PID of the IP.
+**/
+PCH_SBI_PID
+PchPcrGetPid (
+  PCH_IP_PID_ENUM  IpEnum
+  )
+{
+  switch (IpEnum) {
+    case PchIpDmi:
+      return PID_DMI;
+    case PchIpIclk:
+      return PID_ICLK;
+    default:
+      ASSERT (FALSE);
+      return PCH_INVALID_PID;
+  }
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmPchPcrLib/PeiDxeSmmPchPcrLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmPchPcrLib/PeiDxeSmmPchPcrLib.inf
new file mode 100644
index 0000000000..2efeba374f
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/Library/PeiDxeSmmPchPcrLib/PeiDxeSmmPchPcrLib.inf
@@ -0,0 +1,35 @@
+## @file
+# PCH PCR Library.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchPcrLib
+FILE_GUID = 117C8D19-445B-46BF-B624-109F63709375
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchPcrLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PchInfoLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchPcrLib.c
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmPchSbiAccessLib/PchSbiAccessLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmPchSbiAccessLib/PchSbiAccessLib.c
new file mode 100644
index 0000000000..8017dee3aa
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmPchSbiAccessLib/PchSbiAccessLib.c
@@ -0,0 +1,253 @@
+/** @file
+  PCH SBI access library.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <IndustryStandard/Pci30.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PchSbiAccessLib.h>
+#include <Library/PchPciBdfLib.h>
+#include <Register/PchRegs.h>
+#include <Register/P2sbRegs.h>
+
+/**
+  Execute PCH SBI message
+  Take care of that there is no lock protection when using SBI programming in both POST time and SMI.
+  It will clash with POST time SBI programming when SMI happen.
+  Programmer MUST do the save and restore opration while using the PchSbiExecution inside SMI
+  to prevent from racing condition.
+  This function will reveal P2SB and hide P2SB if it's originally hidden. If more than one SBI access
+  needed, it's better to unhide the P2SB before calling and hide it back after done.
+
+  When the return value is "EFI_SUCCESS", the "Response" do not need to be checked as it would have been
+  SBI_SUCCESS. If the return value is "EFI_DEVICE_ERROR", then this would provide additional information
+  when needed.
+
+  @param[in] Pid                        Port ID of the SBI message
+  @param[in] Offset                     Offset of the SBI message
+  @param[in] Opcode                     Opcode
+  @param[in] Posted                     Posted message
+  @param[in, out] Data32                Read/Write data
+  @param[out] Response                  Response
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_DEVICE_ERROR              Transaction fail
+  @retval EFI_INVALID_PARAMETER         Invalid parameter
+  @retval EFI_TIMEOUT                   Timeout while waiting for response
+**/
+EFI_STATUS
+PchSbiExecution (
+  IN     PCH_SBI_PID                    Pid,
+  IN     UINT64                         Offset,
+  IN     PCH_SBI_OPCODE                 Opcode,
+  IN     BOOLEAN                        Posted,
+  IN OUT UINT32                         *Data32,
+  OUT    UINT8                          *Response
+  )
+{
+  return PchSbiExecutionEx ( Pid,
+           Offset,
+           Opcode,
+           Posted,
+           0x000F,
+           0x0000,
+           0x0000,
+           Data32,
+           Response
+           );
+}
+
+/**
+  Full function for executing PCH SBI message
+  Take care of that there is no lock protection when using SBI programming in both POST time and SMI.
+  It will clash with POST time SBI programming when SMI happen.
+  Programmer MUST do the save and restore opration while using the PchSbiExecution inside SMI
+  to prevent from racing condition.
+  This function will reveal P2SB and hide P2SB if it's originally hidden. If more than one SBI access
+  needed, it's better to unhide the P2SB before calling and hide it back after done.
+
+  When the return value is "EFI_SUCCESS", the "Response" do not need to be checked as it would have been
+  SBI_SUCCESS. If the return value is "EFI_DEVICE_ERROR", then this would provide additional information
+  when needed.
+
+  @param[in] Pid                        Port ID of the SBI message
+  @param[in] Offset                     Offset of the SBI message
+  @param[in] Opcode                     Opcode
+  @param[in] Posted                     Posted message
+  @param[in] Fbe                        First byte enable
+  @param[in] Bar                        Bar
+  @param[in] Fid                        Function ID
+  @param[in, out] Data32                Read/Write data
+  @param[out] Response                  Response
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_DEVICE_ERROR              Transaction fail
+  @retval EFI_INVALID_PARAMETER         Invalid parameter
+  @retval EFI_TIMEOUT                   Timeout while waiting for response
+**/
+EFI_STATUS
+PchSbiExecutionEx (
+  IN     PCH_SBI_PID                    Pid,
+  IN     UINT64                         Offset,
+  IN     PCH_SBI_OPCODE                 Opcode,
+  IN     BOOLEAN                        Posted,
+  IN     UINT16                         Fbe,
+  IN     UINT16                         Bar,
+  IN     UINT16                         Fid,
+  IN OUT UINT32                         *Data32,
+  OUT    UINT8                          *Response
+  )
+{
+  UINT64                                P2sbBase;
+  UINTN                                 Timeout;
+  UINT16                                SbiStat;
+
+  //
+  // Check opcode valid
+  //
+  switch (Opcode) {
+    case MemoryRead:
+    case MemoryWrite:
+    case PciConfigRead:
+    case PciConfigWrite:
+    case PrivateControlRead:
+    case PrivateControlWrite:
+    case GpioLockUnlock:
+      break;
+    default:
+      return EFI_INVALID_PARAMETER;
+      break;
+  }
+
+  P2sbBase = P2sbPciCfgBase ();
+  if (PciSegmentRead16 (P2sbBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+    ASSERT (FALSE);
+    return EFI_DEVICE_ERROR;
+  }
+  ///
+  /// BWG Section 2.2.1
+  /// 1. Poll P2SB PCI offset D8h[0] = 0b
+  /// Make sure the previous opeartion is completed.
+  ///
+  Timeout = 0xFFFFFFF;
+  while (Timeout > 0) {
+    SbiStat = PciSegmentRead16 (P2sbBase + R_P2SB_CFG_SBISTAT);
+    if ((SbiStat & B_P2SB_CFG_SBISTAT_INITRDY) == 0) {
+      break;
+    }
+    Timeout--;
+  }
+  if (Timeout == 0) {
+    return EFI_TIMEOUT;
+  }
+  //
+  // Initial Response status
+  //
+  *Response = SBI_INVALID_RESPONSE;
+  SbiStat   = 0;
+  ///
+  /// 2. Write P2SB PCI offset D0h[31:0] with Address and Destination Port ID
+  ///
+  PciSegmentWrite32 (P2sbBase + R_P2SB_CFG_SBIADDR, (UINT32) ((Pid << 24) | (UINT16) Offset));
+  ///
+  /// 3. Write P2SB PCI offset DCh[31:0] with extended address, which is expected to be 0 in CNL PCH.
+  ///
+  PciSegmentWrite32 (P2sbBase + R_P2SB_CFG_SBIEXTADDR, (UINT32) RShiftU64 (Offset, 16));
+  ///
+  /// 5. Set P2SB PCI offset D8h[15:8] = 00000110b for read
+  ///    Set P2SB PCI offset D8h[15:8] = 00000111b for write
+  //
+  // Set SBISTAT[15:8] to the opcode passed in
+  // Set SBISTAT[7] to the posted passed in
+  //
+  PciSegmentAndThenOr16 (
+    (P2sbBase + R_P2SB_CFG_SBISTAT),
+    (UINT16) ~(B_P2SB_CFG_SBISTAT_OPCODE | B_P2SB_CFG_SBISTAT_POSTED),
+    (UINT16) ((Opcode << 8) | (Posted << 7))
+    );
+  ///
+  /// 6. Write P2SB PCI offset DAh[15:0] = F000h
+  ///
+  //
+  // Set RID[15:0] = Fbe << 12 | Bar << 8 | Fid
+  //
+  PciSegmentWrite16 (
+    (P2sbBase + R_P2SB_CFG_SBIRID),
+    (((Fbe & 0x000F) << 12) | ((Bar & 0x0007) << 8) | (Fid & 0x00FF))
+    );
+
+  switch (Opcode) {
+    case MemoryWrite:
+    case PciConfigWrite:
+    case PrivateControlWrite:
+    case GpioLockUnlock:
+      ///
+      /// 4. Write P2SB PCI offset D4h[31:0] with the intended data accordingly
+      ///
+      PciSegmentWrite32 ((P2sbBase + R_P2SB_CFG_SBIDATA), *Data32);
+      break;
+    default:
+      ///
+      /// 4. Write P2SB PCI offset D4h[31:0] with dummy data such as 0,
+      /// because all D0-DFh register range must be touched in CNL PCH
+      /// for a successful SBI transaction.
+      ///
+      PciSegmentWrite32 ((P2sbBase + R_P2SB_CFG_SBIDATA), 0);
+      break;
+  }
+  ///
+  /// 7. Set P2SB PCI offset D8h[0] = 1b, Poll P2SB PCI offset D8h[0] = 0b
+  ///
+  //
+  // Set SBISTAT[0] = 1b, trigger the SBI operation
+  //
+  PciSegmentOr16 (P2sbBase + R_P2SB_CFG_SBISTAT, (UINT16) B_P2SB_CFG_SBISTAT_INITRDY);
+  //
+  // Poll SBISTAT[0] = 0b, Polling for Busy bit
+  //
+  Timeout = 0xFFFFFFF;
+  while (Timeout > 0) {
+    SbiStat = PciSegmentRead16 (P2sbBase + R_P2SB_CFG_SBISTAT);
+    if ((SbiStat & B_P2SB_CFG_SBISTAT_INITRDY) == 0) {
+      break;
+    }
+    Timeout--;
+  }
+  if (Timeout == 0) {
+    //
+    // If timeout, it's fatal error.
+    //
+    return EFI_TIMEOUT;
+  } else {
+    ///
+    /// 8. Check if P2SB PCI offset D8h[2:1] = 00b for successful transaction
+    ///
+    *Response = (UINT8) ((SbiStat & B_P2SB_CFG_SBISTAT_RESPONSE) >> N_P2SB_CFG_SBISTAT_RESPONSE);
+    if (*Response == SBI_SUCCESSFUL) {
+      switch (Opcode) {
+        case MemoryRead:
+        case PciConfigRead:
+        case PrivateControlRead:
+          ///
+          /// 9. Read P2SB PCI offset D4h[31:0] for SBI data
+          ///
+          *Data32 = PciSegmentRead32 (P2sbBase + R_P2SB_CFG_SBIDATA);
+          break;
+        default:
+          break;
+      }
+      return EFI_SUCCESS;
+    } else if (*Response == SBI_POWERDOWN) {
+      return EFI_NO_RESPONSE;
+    } else {
+      return EFI_DEVICE_ERROR;
+    }
+  }
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmPchSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmPchSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf
new file mode 100644
index 0000000000..4199a0a6c7
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmPchSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf
@@ -0,0 +1,36 @@
+## @file
+# PCH SBI access library.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchSbiAccessLib
+FILE_GUID = 96ECB0FB-A975-4DC8-B88A-D90C3378CE87
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchSbiAccessLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PciSegmentLib
+PchPciBdfLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchSbiAccessLib.c
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 22/40] TigerlakeSiliconPkg/IpBlock: Add PchDmi component
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (19 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 21/40] TigerlakeSiliconPkg/IpBlock: Add P2sb component Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 23/40] TigerlakeSiliconPkg/IpBlock: Add PcieRp component Heng Luo
                   ` (17 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * IpBlock/PchDmi/IncludePrivate
  * IpBlock/PchDmi/LibraryPrivate

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/IncludePrivate/Library/PchDmiLib.h                             | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PchDmi14.c                   |  50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PchDmi14.h                   |  34 ++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PchDmiLib.c                  | 269 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PchDmiWithS3Lib.c            |  73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiLib.inf       |  42 ++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiWithS3Lib.inf |  41 +++++++++++++++++++++++++++++++++++++++++
 7 files changed, 684 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/IncludePrivate/Library/PchDmiLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/IncludePrivate/Library/PchDmiLib.h
new file mode 100644
index 0000000000..77db69c75a
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/IncludePrivate/Library/PchDmiLib.h
@@ -0,0 +1,175 @@
+/** @file
+  Header file for PchDmiLib.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_DMI_LIB_H_
+#define _PCH_DMI_LIB_H_
+
+/**
+  This function checks if DMI Secured Register Lock (SRL) is set
+
+  @retval SRL state
+**/
+BOOLEAN
+IsPchDmiLocked (
+  VOID
+  );
+
+/**
+  Get PCH TCO base address.
+
+  @retval Address                   Address of TCO base address.
+**/
+UINT16
+PchDmiGetTcoBase (
+  VOID
+  );
+
+/**
+  Set PCH LPC/eSPI generic IO range decoding in DMI
+
+  @param[in] Address                    Address for generic IO range base address.
+  @param[in] Length                     Length of generic IO range.
+  @param[in] RangeIndex                 Index of choosen range
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiSetLpcGenIoRange (
+  IN  UINT32                            Address,
+  IN  UINT32                            Length,
+  IN  UINT32                            RangeIndex
+  );
+
+/**
+  Set PCH eSPI eSPI CS1# generic IO range decoding in DMI
+
+  @param[in] Address                    Address for generic IO range base address.
+  @param[in] Length                     Length of generic IO range.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiSetEspiCs1GenIoRange (
+  IN  UINT32                            Address,
+  IN  UINT32                            Length
+  );
+
+/**
+  Set PCH LPC/eSPI memory range decoding in DMI
+
+  @param[in] Address                    Address for memory base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiSetLpcMemRange (
+  IN  UINT32                            Address
+  );
+
+/**
+  Set PCH eSPI CS1# memory range decoding in DMI
+
+  @param[in] Address                    Address for memory base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiSetEspiCs1MemRange (
+  IN  UINT32                            Address
+  );
+
+/**
+  Check if Boot BIOS Strap is set for SPI.
+
+  @retval TRUE                Boot BIOS Strap set for SPI
+  @retval FALSE               Boot BIOS Strap set for LPC/eSPI
+**/
+BOOLEAN
+PchDmiIsBootBiosStrapSetForSpi (
+  VOID
+  );
+
+/**
+  Set PCH BIOS range decoding in DMI
+  Please check EDS for detail of BiosDecodeEnable bit definition.
+    bit 15: F8-FF Enable
+    bit 14: F0-F8 Enable
+    bit 13: E8-EF Enable
+    bit 12: E0-E8 Enable
+    bit 11: D8-DF Enable
+    bit 10: D0-D7 Enable
+    bit  9: C8-CF Enable
+    bit  8: C0-C7 Enable
+    bit  7: Legacy F Segment Enable
+    bit  6: Legacy E Segment Enable
+    bit  5: Reserved
+    bit  4: Reserved
+    bit  3: 70-7F Enable
+    bit  2: 60-6F Enable
+    bit  1: 50-5F Enable
+    bit  0: 40-4F Enable
+
+  @param[in] BiosDecodeEnable           Bios decode enable setting.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiSetBiosDecodeEnable (
+  IN  UINT16                            BiosDecodeEnable
+  );
+
+/**
+  Set PCH LPC/eSPI IO decode ranges in DMI
+  Please check EDS for detail of LPC/eSPI IO decode ranges bit definition.
+  Bit  12: FDD range
+  Bit 9:8: LPT range
+  Bit 6:4: ComB range
+  Bit 2:0: ComA range
+
+  @param[in] LpcIoDecodeRanges          LPC/eSPI IO decode ranges bit settings.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiSetLpcIoDecodeRanges (
+  IN  UINT16                            LpcIoDecodeRanges
+  );
+
+/**
+  Set PCH LPC/eSPI IO enable decoding in DMI
+
+  @param[in] LpcIoEnableDecoding        LPC/eSPI IO enable decoding bit settings.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiSetLpcIoEnable (
+  IN  UINT16                            LpcIoEnableDecoding
+  );
+
+/**
+  Configure PCH DMI Lock
+**/
+VOID
+PchDmiSetLockWithS3BootScript (
+  VOID
+  );
+
+/**
+  Set BIOS interface Lock-Down
+**/
+VOID
+PchDmiSetBiosLockDownWithS3BootScript (
+  VOID
+  );
+#endif // _PCH_DMI_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PchDmi14.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PchDmi14.c
new file mode 100644
index 0000000000..60bc29c431
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PchDmi14.c
@@ -0,0 +1,50 @@
+/** @file
+  This file contains functions for PCH DMI SIP14
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchDmiLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchInfoLib.h>
+#include <Register/PchDmiRegs.h>
+#include <Register/PchDmi14Regs.h>
+#include <Register/PchPcrRegs.h>
+
+/**
+  This function checks if DMI SIP14 Secured Register Lock (SRL) is set
+
+  @retval SRL state
+**/
+BOOLEAN
+IsPchDmi14Locked (
+  VOID
+  )
+{
+  return ((PchPcrRead32 (PID_DMI, R_PCH_DMI14_PCR_DMIC) & B_PCH_DMI14_PCR_DMIC_SRL) != 0);
+}
+
+/**
+ Secure Register Lock data
+
+ @param[out] SrlRegOffset        Register offset holding Secure Register Lock setting
+ @param[out] SrlRegMask          Mask for Secure Register Lock setting
+**/
+VOID
+PchDmi14SrlRegData (
+  OUT UINT16  *SrlRegOffset,
+  OUT UINT32  *SrlRegMask
+  )
+{
+  *SrlRegMask = B_PCH_DMI14_PCR_DMIC_SRL;
+  *SrlRegOffset = R_PCH_DMI14_PCR_DMIC;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PchDmi14.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PchDmi14.h
new file mode 100644
index 0000000000..4c19ad82d7
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PchDmi14.h
@@ -0,0 +1,34 @@
+/** @file
+  Internal header file for PCH DMI library for SIP14
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef __PCH_DMI_14_H__
+#define __PCH_DMI_14_H__
+
+#include <Library/PchDmiLib.h>
+
+/**
+  This function checks if DMI SIP14 Secured Register Lock (SRL) is set
+
+  @retval SRL state
+**/
+BOOLEAN
+IsPchDmi14Locked (
+  VOID
+  );
+
+/**
+ Secure Register Lock data
+
+ @param[out] SrlRegOffset        Register offset holding Secure Register Lock setting
+ @param[out] SrlRegMask          Mask for Secure Register Lock setting
+**/
+VOID
+PchDmi14SrlRegData (
+  OUT UINT16  *SrlRegOffset,
+  OUT UINT32  *SrlRegMask
+  );
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PchDmiLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PchDmiLib.c
new file mode 100644
index 0000000000..972e5145aa
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PchDmiLib.c
@@ -0,0 +1,269 @@
+/** @file
+  PCH DMI library.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchDmiLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Register/PchPcrRegs.h>
+#include <Register/PchDmiRegs.h>
+#include <Register/PchRegsLpc.h>
+
+#include "PchDmi14.h"
+
+/**
+  This function checks if DMI Secured Register Lock (SRL) is set
+
+  @retval SRL state
+**/
+BOOLEAN
+IsPchDmiLocked (
+  VOID
+  )
+{
+  return IsPchDmi14Locked ();
+}
+
+/**
+  Get PCH TCO base address.
+
+  @retval Address                   Address of TCO base address.
+**/
+UINT16
+PchDmiGetTcoBase (
+  VOID
+  )
+{
+  //
+  // Read "TCO Base Address" PCR[DMI] + 2778h[15:5]
+  //
+  return (PchPcrRead16 (PID_DMI, R_PCH_DMI_PCR_TCOBASE) & B_PCH_DMI_PCR_TCOBASE_TCOBA);
+}
+
+/**
+  Set PCH LPC/eSPI generic IO range decoding in DMI
+
+  @param[in] Address                    Address for generic IO range base address.
+  @param[in] Length                     Length of generic IO range.
+  @param[in] RangeIndex                 Index of choosen range
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiSetLpcGenIoRange (
+  IN  UINT32                            Address,
+  IN  UINT32                            Length,
+  IN  UINT32                            RangeIndex
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Set PCH eSPI eSPI CS1# generic IO range decoding in DMI
+
+  @param[in] Address                    Address for generic IO range base address.
+  @param[in] Length                     Length of generic IO range.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiSetEspiCs1GenIoRange (
+  IN  UINT32                            Address,
+  IN  UINT32                            Length
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Set PCH LPC/eSPI memory range decoding in DMI
+
+  @param[in] Address                    Address for memory base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiSetLpcMemRange (
+  IN  UINT32                            Address
+  )
+{
+  if (IsPchDmiLocked ()) {
+    DEBUG ((DEBUG_ERROR, "%a Error. DMI is locked.\n", __FUNCTION__));
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Program LPC Memory Range, PCR[DMI] + 2740h to the same value programmed in LPC/eSPI PCI Offset 98h.
+  //
+  PchPcrWrite32 (
+    PID_DMI, R_PCH_DMI_PCR_LPCGMR,
+    (Address | B_LPC_CFG_LGMR_LMRD_EN)
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Set PCH eSPI CS1# memory range decoding in DMI
+
+  @param[in] Address                    Address for memory base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiSetEspiCs1MemRange (
+  IN  UINT32                            Address
+  )
+{
+  if (IsPchDmiLocked ()) {
+    DEBUG ((DEBUG_ERROR, "%a Error. DMI is locked.\n", __FUNCTION__));
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Program LPC Memory Range, PCR[DMI] + 27C0h to the same value programmed in eSPI PCI Offset A8h.
+  //
+  PchPcrWrite32 (
+    PID_DMI, R_PCH_DMI_PCR_SEGMR,
+    (Address | B_LPC_CFG_LGMR_LMRD_EN)
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Check if Boot BIOS Strap is set for SPI.
+
+  @retval TRUE                Boot BIOS Strap set for SPI
+  @retval FALSE               Boot BIOS Strap set for LPC/eSPI
+**/
+BOOLEAN
+PchDmiIsBootBiosStrapSetForSpi (
+  VOID
+  )
+{
+  //
+  // Check General Control and Status (GCS) [10]
+  // '0': SPI
+  // '1': LPC/eSPI
+  //
+  return ((PchPcrRead32 (PID_DMI, R_PCH_DMI_PCR_GCS) & B_PCH_DMI_PCR_BBS) != B_PCH_DMI_PCR_BBS);
+}
+
+/**
+  Set PCH BIOS range decoding in DMI
+  Please check EDS for detail of BiosDecodeEnable bit definition.
+    bit 15: F8-FF Enable
+    bit 14: F0-F8 Enable
+    bit 13: E8-EF Enable
+    bit 12: E0-E8 Enable
+    bit 11: D8-DF Enable
+    bit 10: D0-D7 Enable
+    bit  9: C8-CF Enable
+    bit  8: C0-C7 Enable
+    bit  7: Legacy F Segment Enable
+    bit  6: Legacy E Segment Enable
+    bit  5: Reserved
+    bit  4: Reserved
+    bit  3: 70-7F Enable
+    bit  2: 60-6F Enable
+    bit  1: 50-5F Enable
+    bit  0: 40-4F Enable
+
+  @param[in] BiosDecodeEnable           Bios decode enable setting.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiSetBiosDecodeEnable (
+  IN  UINT16                            BiosDecodeEnable
+  )
+{
+  if (IsPchDmiLocked ()) {
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // program LPC BIOS Decode Enable, PCR[DMI] + 2744h to the same value programmed in LPC or SPI Offset D8h.
+  //
+  PchPcrWrite16 (PID_DMI, R_PCH_DMI_PCR_LPCBDE, BiosDecodeEnable);
+  return EFI_SUCCESS;
+}
+
+/**
+  Set PCH LPC/eSPI IO decode ranges in DMI
+  Please check EDS for detail of LPC/eSPI IO decode ranges bit definition.
+  Bit  12: FDD range
+  Bit 9:8: LPT range
+  Bit 6:4: ComB range
+  Bit 2:0: ComA range
+
+  @param[in] LpcIoDecodeRanges          LPC/eSPI IO decode ranges bit settings.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiSetLpcIoDecodeRanges (
+  IN  UINT16                            LpcIoDecodeRanges
+  )
+{
+  //
+  // This cycle decoding is only allowed to set when DMI is not locked.
+  //
+  if (IsPchDmiLocked ()) {
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // program LPC I/O Decode Ranges, PCR[DMI] + 2770h[15:0] to the same value programmed in LPC/eSPI PCI offset 80h.
+  //
+  PchPcrWrite16 (PID_DMI, R_PCH_DMI_PCR_LPCIOD, LpcIoDecodeRanges);
+  return EFI_SUCCESS;
+}
+
+/**
+  Set PCH LPC/eSPI IO enable decoding in DMI
+
+  @param[in] LpcIoEnableDecoding        LPC/eSPI IO enable decoding bit settings.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchDmiSetLpcIoEnable (
+  IN  UINT16                            LpcIoEnableDecoding
+  )
+{
+  //
+  // This cycle decoding is only allowed to set when DMI is not locked.
+  //
+  if (IsPchDmiLocked ()) {
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // program LPC I/O Decode Ranges, PCR[DMI] + 2774h[15:0] to the same value programmed in LPC/eSPI PCI offset 82h.
+  //
+  PchPcrWrite16 (PID_DMI, R_PCH_DMI_PCR_LPCIOE, LpcIoEnableDecoding);
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PchDmiWithS3Lib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PchDmiWithS3Lib.c
new file mode 100644
index 0000000000..7d6801ee57
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PchDmiWithS3Lib.c
@@ -0,0 +1,73 @@
+/** @file
+  PCH DMI library with S3 boot script support.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Register/PchPcrRegs.h>
+#include <Register/PchDmiRegs.h>
+
+#include "PchDmi14.h"
+
+/**
+  Configure DMI Lock
+**/
+VOID
+PchDmiSetLockWithS3BootScript (
+  VOID
+  )
+{
+  UINT32  Data32Or;
+  UINT32  Data32And;
+  UINT16  Address;
+
+  Data32And = 0xFFFFFFFF;
+
+  PchDmi14SrlRegData (&Address, &Data32Or);
+
+  PchPcrAndThenOr32 (
+    PID_DMI, Address,
+    Data32And,
+    Data32Or
+    );
+  PCH_PCR_BOOT_SCRIPT_READ_WRITE (
+    S3BootScriptWidthUint32,
+    PID_DMI, Address,
+    &Data32Or,
+    &Data32And
+    );
+}
+
+/**
+  Set BIOS interface Lock-Down
+**/
+VOID
+PchDmiSetBiosLockDownWithS3BootScript (
+  VOID
+  )
+{
+  UINT32  Data32Or;
+  UINT32  Data32And;
+
+  //
+  // Set BIOS Lock-Down (BILD)
+  // When set, prevents GCS.BBS from being changed
+  //
+  Data32And = 0xFFFFFFFF;
+  Data32Or = B_PCH_DMI_PCR_BILD;
+  PchPcrAndThenOr32 (PID_DMI, R_PCH_DMI_PCR_GCS, Data32And, Data32Or);
+  PCH_PCR_BOOT_SCRIPT_READ_WRITE (
+    S3BootScriptWidthUint32,
+    PID_DMI, R_PCH_DMI_PCR_GCS,
+    &Data32Or,
+    &Data32And
+    );
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiLib.inf
new file mode 100644
index 0000000000..d33310dd76
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiLib.inf
@@ -0,0 +1,42 @@
+## @file
+#  Component description file for the PeiDxeSmmPchDmiLib
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION                    = 0x00010017
+BASE_NAME                      = PeiDxeSmmPchDmiLib
+FILE_GUID                      = 067DC1C4-2668-4F06-9921-307514B66B34
+VERSION_STRING                 = 1.0
+MODULE_TYPE                    = BASE
+LIBRARY_CLASS                  = PchDmiLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[LibraryClasses]
+  BaseLib
+  IoLib
+  DebugLib
+  PchInfoLib
+  PchPcrLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+  PchDmiLib.c
+  PchDmi14.c
+  PchDmi14.h
+
+[Guids]
+  gPchDmiConfigGuid         ## CONSUMES
+
+[Pcd]
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiWithS3Lib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiWithS3Lib.inf
new file mode 100644
index 0000000000..9381a7b5fd
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiWithS3Lib.inf
@@ -0,0 +1,41 @@
+## @file
+#  Component description file for the PeiDxeSmmPchDmiWithS3Lib
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION                    = 0x00010017
+BASE_NAME                      = PeiDxeSmmPchDmiWithS3Lib
+FILE_GUID                      = 32CCA047-6AF0-46FF-83DA-32BA62484075
+VERSION_STRING                 = 1.0
+MODULE_TYPE                    = BASE
+LIBRARY_CLASS                  = PchDmiWithS3Lib
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[LibraryClasses]
+  BaseLib
+  IoLib
+  DebugLib
+  PchPcrLib
+  PchInfoLib
+  S3BootScriptLib
+  PchDmiLib
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+  PchDmiWithS3Lib.c
+  PchDmi14.h
+
+[pcd]
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 23/40] TigerlakeSiliconPkg/IpBlock: Add PcieRp component
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (20 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 22/40] TigerlakeSiliconPkg/IpBlock: Add PchDmi component Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 24/40] TigerlakeSiliconPkg/IpBlock: Add Pmc component Heng Luo
                   ` (16 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * IpBlock/PcieRp/IncludePrivate
  * IpBlock/PcieRp/Library
  * IpBlock/PcieRp/LibraryPrivate

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/IncludePrivate/Library/DxePchPcieRpPolicyLib.h                            |   55 ++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/IncludePrivate/Library/PciExpressHelpersLib.h                             |  173 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/IncludePrivate/Library/PcieRpLib.h                                        |  109 ++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/IncludePrivate/Register/PcieSipRegs.h                                     |   45 ++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/Library/BasePcieHelperLib/BasePcieHelperLib.c                             |  315 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/Library/BasePcieHelperLib/BasePcieHelperLib.inf                           |   37 +++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/Library/PeiDxeSmmPchPcieRpLib/PchPcieRpLib.c                              |   69 ++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/Library/PeiDxeSmmPchPcieRpLib/PchPcieRpLibInternal.h                      |   20 +++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/Library/PeiDxeSmmPchPcieRpLib/PchPcieRpLibVer2.c                          |  128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/Library/PeiDxeSmmPchPcieRpLib/PeiDxeSmmPchPcieRpLibVer2.inf               |   39 +++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/DxePchPcieRpPolicyLib/DxePchPcieRpPolicyLib.c              |  179 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/DxePchPcieRpPolicyLib/DxePchPcieRpPolicyLib.inf            |   30 ++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/PciExpressHelpersLibrary/PciExpressHelpersLibrary.c        | 1997 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/PciExpressHelpersLibrary/PciExpressHelpersLibrary.h        |   40 ++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/PciExpressHelpersLibrary/PeiDxeSmmPciExpressHelpersLib.inf |   49 ++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/PcieClientRpLib/PcieClientRpLib.c                          |  247 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/PcieClientRpLib/PcieClientRpLib.inf                        |   43 +++++++++++++++++++
 17 files changed, 3575 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/IncludePrivate/Library/DxePchPcieRpPolicyLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/IncludePrivate/Library/DxePchPcieRpPolicyLib.h
new file mode 100644
index 0000000000..1dea61388e
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/IncludePrivate/Library/DxePchPcieRpPolicyLib.h
@@ -0,0 +1,55 @@
+/** @file
+  DXE PcieRp policy library.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _DXE_PCH_PCIERP_POLICY_LIB_H_
+#define _DXE_PCH_PCIERP_POLICY_LIB_H_
+
+#include <Protocol/PchPolicy.h>
+
+/**
+  Load DXE Config block default for Pch PCIE RP
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadPchPcieRpDxeConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  );
+
+/**
+  Print PCIE_RP_DXE_CONFIG.
+
+  @param[in] PchPolicy            Pointer to a PCH_POLICY_PROTOCOL
+**/
+VOID
+PchPcieRpDxePrintConfig (
+  IN PCH_POLICY_PROTOCOL    *PchPolicy
+  );
+
+/**
+  Get PchPcieRp config block table size.
+
+  @retval      Size of config block
+**/
+UINT16
+PchPcieRpDxeGetConfigBlockTotalSize (
+  VOID
+  );
+
+/**
+  Add PchPcieRp ConfigBlock.
+
+  @param[in] ConfigBlockTableAddress    The pointer to config block table
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+PchPcieRpDxeAddConfigBlock (
+  IN VOID           *ConfigBlockTableAddress
+  );
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/IncludePrivate/Library/PciExpressHelpersLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/IncludePrivate/Library/PciExpressHelpersLib.h
new file mode 100644
index 0000000000..d7ca34dc38
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/IncludePrivate/Library/PciExpressHelpersLib.h
@@ -0,0 +1,173 @@
+/** @file
+  Header file for PCI Express helpers library
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCI_EXPRESS_HELPERS_LIB_H_
+#define _PCI_EXPRESS_HELPERS_LIB_H_
+
+#include <PchPolicyCommon.h>
+#include <Library/PcieRpLib.h>
+
+typedef enum {
+  TpoScale2us,
+  TpoScale10us,
+  TpoScale100us,
+  TpoScaleMax
+} T_PO_SCALE;
+//
+// This structure keeps segment:bus:device:function coordinates of a PCIe device
+// in a single variable. PcieCap is offset to PCI Express capabilities.
+//
+typedef struct {
+  UINT32 Seg : 8;
+  UINT32 Bus : 8;
+  UINT32 Dev : 5;
+  UINT32 Func : 3;
+  UINT32 PcieCap : 8;
+} SBDF;
+
+/*
+  Converts Tpower_on from value:scale notation to microseconds
+
+  @param[in] TpoScale   T power on scale
+  @param[in] TpoValue   T power on value
+
+  @retval    number of microseconds
+*/
+UINT32
+TpoToUs (
+  UINT32 TpoScale,
+  UINT32 TpoValue
+  );
+
+/**
+PCIe controller Sku.
+**/
+
+typedef enum {
+  EnumPchPcie = 0,
+  EnumiTbtPcie = 1,
+  EnumCpuPcie = 2,
+  EnumPciSkuMax = 3
+} PCI_SKU;
+
+/*
+  Initializes the following features in rootport and devices behind it:
+  Maximum Payload Size (generic)
+  Rootport packet split (proprietary)
+  EonOfInterrupt forwarding (proprietary)
+  Common Clock Configuration (generic)
+
+  Generic: any code written according to PCIE Express base specification can do that.
+  Proprietary: code uses registers and features that are specific to Intel silicon
+  and probably only this Reference Code knows how to handle that.
+
+  If OEM implemented generic feature enabling in his platform code or trusts Operating System
+  to do it, then those features can be deleted from here.
+
+  CCC requires link retrain, which takes a while. CCC must happen before L0s/L1 programming.
+  If there was guarantee no code would access PCI while links retrain, it would be possible to skip this waiting
+
+  @param[in] RpSegment  address of rootport on PCIe
+  @param[in] RpBus      address of rootport on PCIe
+  @param[in] RpDevice   address of rootport on PCIe
+  @param[in] RpFunction address of rootport on PCIe
+  @param[in] BusMin     minimum Bus number that can be assigned below this rootport
+  @param[in] BusMax     maximum Bus number that can be assigned below this rootport
+*/
+VOID
+RootportDownstreamConfiguration (
+  UINT8                     RpSegment,
+  UINT8                     RpBus,
+  UINT8                     RpDevice,
+  UINT8                     RpFunction,
+  UINT8                     BusMin,
+  UINT8                     BusMax,
+  PCI_SKU                   PciSku
+  );
+
+/*
+  Configures the following power-management related features in rootport and devices behind it:
+  LTR limit (generic)
+  LTR override (proprietary)
+  Clock Power Management (generic)
+  L1 substates (generic except for the override table)
+  L1.LOW substate (proprietary)
+  L0s and L1 (generic)
+
+  Generic: any code written according to PCIE Express base specification can do that.
+  Proprietary: code uses registers and features that are specific to Intel silicon
+  and probably only this Reference Code knows how to handle that.
+
+  If OEM implemented generic feature enabling in his platform code or trusts Operating System
+  to do it, then those features can be deleted from here.
+
+  @param[in] RpSegment                address of rootport on PCIe
+  @param[in] RpBus                    address of rootport on PCIe
+  @param[in] RpDevice                 address of rootport on PCIe
+  @param[in] RpFunction               address of rootport on PCIe
+  @param[in] BusMin                   minimal Bus number that can be assigned below this rootport
+  @param[in] BusMax                   maximum Bus number that can be assigned below this rootport
+  @param[in] PcieRpCommonConfig       a pointer to Pcie Root Port Common Config
+  @param[in] AspmOverrideTableSize    size of override array
+  @param[in] AspmOverrideTable        array of device that need exceptions in configuration
+*/
+VOID
+RootportDownstreamPmConfiguration (
+  UINT8                               RpSegment,
+  UINT8                               RpBus,
+  UINT8                               RpDevice,
+  UINT8                               RpFunction,
+  UINT8                               BusMin,
+  UINT8                               BusMax,
+  PCIE_ROOT_PORT_COMMON_CONFIG        *PcieRpCommonConfig,
+  UINT32                              AspmOverrideTableSize,
+  PCH_PCIE_DEVICE_OVERRIDE            *AspmOverrideTable
+  );
+
+typedef struct {
+  UINT32 MaxSnoopLatencyValue         : 10;
+  UINT32 MaxSnoopLatencyScale         : 3;
+  UINT32 MaxNoSnoopLatencyValue       : 10;
+  UINT32 MaxNoSnoopLatencyScale       : 3;
+  UINT32 Reserved                     : 6;
+} LTR_LIMIT;
+
+/**
+  Checks if given PCI device is capable of Latency Tolerance Reporting
+
+  @param[in] Sbdf            device's segment:bus:device:function coordinates
+
+  @retval TRUE if yes
+**/
+BOOLEAN
+IsLtrCapable (
+  SBDF Sbdf
+  );
+
+/**
+  Returns combination of two LTR override values
+  The resulting LTR override separately chooses stricter limits for snoop and nosnoop
+
+  @param[in] LtrA      LTR override values to be combined
+  @param[in] LtrB      LTR override values to be combined
+
+  @retval LTR override value
+**/
+LTR_OVERRIDE
+CombineLtr (
+  LTR_OVERRIDE LtrA,
+  LTR_OVERRIDE LtrB
+  );
+
+/**
+  Extended Virtual Channel Configuration
+**/
+typedef struct {
+  UINT16 CapOffset;
+  UINT8  ExtVcCount;
+} MULTI_VC_SUPPORT;
+
+#endif // _PCI_EXPRESS_HELPERS_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/IncludePrivate/Library/PcieRpLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/IncludePrivate/Library/PcieRpLib.h
new file mode 100644
index 0000000000..ed75e438c7
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/IncludePrivate/Library/PcieRpLib.h
@@ -0,0 +1,109 @@
+/** @file
+  Header file for PCH PCI Express helpers library
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCIE_RP_LIB_
+#define _PCIE_RP_LIB_
+
+#include <PchPolicyCommon.h>
+
+typedef struct {
+  UINT32 MaxSnoopLatencyValue         : 10;
+  UINT32 MaxSnoopLatencyScale         : 3;
+  UINT32 MaxSnoopLatencyRequirement   : 1;
+  UINT32 MaxNoSnoopLatencyValue       : 10;
+  UINT32 MaxNoSnoopLatencyScale       : 3;
+  UINT32 MaxNoSnoopLatencyRequirement : 1;
+  UINT32 ForceOverride                : 1;
+} LTR_OVERRIDE;
+
+/**
+  Get PCIe port number for enabled Root Port.
+
+  @param[in] RpBase    Root Port pci segment base address
+
+  @retval Root Port number (1 based)
+**/
+UINT32
+PciePortNum (
+  IN     UINT64  RpBase
+  );
+
+/**
+  Get PCIe root port index
+  @param[in] RpBase    Root Port pci segment base address
+  @return Root Port index (0 based)
+**/
+UINT32
+PciePortIndex (
+  IN     UINT64  RpBase
+  );
+
+/**
+  This function checks whether PHY lane power gating is enabled on the port.
+
+  @param[in] RpBase                 Root Port base address
+
+  @retval TRUE                      PHY power gating is enabled
+  @retval FALSE                     PHY power gating disabled
+**/
+BOOLEAN
+PcieIsPhyLanePgEnabled (
+  IN     UINT64  RpBase
+  );
+
+/**
+  Configures Root Port packet split.
+
+  @param[in] Segment,Bus,Device,Function    address of currently visited PCIe device
+  @param[in] Mps                            maximum packet size
+**/
+VOID
+ConfigureRpPacketSplit (
+  UINT64 RpBase,
+  UINT8  Mps
+  );
+
+/**
+  Configures LTR override in Root Port's proprietary registers.
+
+  @param[in] Segment,Bus,Device,Function    address of currently visited PCIe device
+  @param[in] LtrConfig                      Root Port LTR configuration
+  @param[in] AspmOverride                   combination of LTR override values from all devices under this Root Port
+**/
+VOID
+ConfigureRpLtrOverride (
+  UINT64           RpBase,
+  UINT32           DevNum,
+  LTR_OVERRIDE     *TreeLtr,
+  PCIE_LTR_CONFIG  *LtrConfig
+  );
+
+/**
+  This function configures EOI message forwarding for PCIe port.
+  If there's an IoAPIC behind this port, forwarding will be enabled
+  Otherwise it will be disabled to minimize bus traffic
+
+  @param[in] Segment,Bus,Device,Function    address of currently visited PCIe device
+  @param[in] IoApicPresent  TRUE if there's IoAPIC behind this Root Port
+**/
+VOID
+ConfigureEoiForwarding (
+  UINT64   RpBase,
+  BOOLEAN  IoApicPresent
+  );
+
+/**
+  Configures proprietary parts of L1 substates configuration in Root Port
+
+  @param[in] RpSbdf       segment:bus:device:function coordinates of Root Port
+  @param[in] LtrCapable   TRUE if Root Port is LTR capable
+**/
+VOID
+L1ssProprietaryConfiguration (
+  UINT64  RpBase,
+  BOOLEAN LtrCapable
+  );
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/IncludePrivate/Register/PcieSipRegs.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/IncludePrivate/Register/PcieSipRegs.h
new file mode 100644
index 0000000000..1fc470b8ba
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/IncludePrivate/Register/PcieSipRegs.h
@@ -0,0 +1,45 @@
+/** @file
+  Register names for PCIe SIP specific registers
+
+  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 _PCIE_SIP_RP_REGS_H_
+#define _PCIE_SIP_RP_REGS_H_
+
+#include <PcieRegs.h>
+
+#define R_PCIE_CFG_CCFG                               0xD0
+#define B_PCIE_CFG_CCFG_UNRS                          (BIT6 | BIT5 | BIT4)
+#define N_PCIE_CFG_CCFG_UNRS                          4
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/Library/BasePcieHelperLib/BasePcieHelperLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/Library/BasePcieHelperLib/BasePcieHelperLib.c
new file mode 100644
index 0000000000..1b3e629431
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/Library/BasePcieHelperLib/BasePcieHelperLib.c
@@ -0,0 +1,315 @@
+/** @file
+  This file contains routines that support PCI Express initialization
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Library/PcieHelperLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <PcieRegs.h>
+
+#define ASPM_L1_NO_LIMIT 0xFF
+#define LINK_RETRAIN_WAIT_TIME 1000 // microseconds
+
+/**
+  Finds the Offset to a given Capabilities ID
+  Each capability has an ID and a pointer to next Capability, so they form a linked list.
+  This function walks the list of Capabilities present in device's pci cfg. If requested capability
+  can be found, its offset is returned.
+  If the capability can't be found or if device doesn't exist, function returns 0
+  CAPID list:
+    0x01 = PCI Power Management Interface
+    0x04 = Slot Identification
+    0x05 = MSI Capability
+    0x10 = PCI Express Capability
+
+  @param[in] DeviceBase           device's base address
+  @param[in] CapId                CAPID to search for
+
+  @retval 0                       CAPID not found (this includes situation where device doesn't exit)
+  @retval Other                   CAPID found, Offset of desired CAPID
+**/
+UINT8
+PcieBaseFindCapId (
+  IN UINT64  DeviceBase,
+  IN UINT8   CapId
+  )
+{
+  UINT8  CapHeaderOffset;
+  UINT8  CapHeaderId;
+  UINT16 Data16;
+  //
+  // We do not explicitly check if device exists to save time and avoid unnecessary PCI access
+  // If the device doesn't exist, check for CapHeaderId != 0xFF will fail and function will return offset 0
+  //
+  if ((PciSegmentRead8 (DeviceBase + PCI_PRIMARY_STATUS_OFFSET) & EFI_PCI_STATUS_CAPABILITY) == 0x00) {
+    ///
+    /// Function has no capability pointer
+    ///
+    return 0;
+  } else {
+    ///
+    /// Check the header layout to determine the Offset of Capabilities Pointer Register
+    ///
+    if ((PciSegmentRead8 (DeviceBase + PCI_HEADER_TYPE_OFFSET) & HEADER_LAYOUT_CODE) == (HEADER_TYPE_CARDBUS_BRIDGE)) {
+      ///
+      /// If CardBus bridge, start at Offset 0x14
+      ///
+      CapHeaderOffset = EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR;
+    } else {
+      ///
+      /// Otherwise, start at Offset 0x34
+      ///
+      CapHeaderOffset = PCI_CAPBILITY_POINTER_OFFSET;
+    }
+    ///
+    /// Get Capability Header, A pointer value of 00h is used to indicate the last capability in the list.
+    ///
+    CapHeaderId     = 0;
+    CapHeaderOffset = PciSegmentRead8 (DeviceBase + CapHeaderOffset) & ((UINT8) ~(BIT0 | BIT1));
+    while (CapHeaderOffset != 0 && CapHeaderId != 0xFF) {
+      Data16 = PciSegmentRead16 (DeviceBase + CapHeaderOffset);
+      CapHeaderId = (UINT8)(Data16 & 0xFF);
+      if (CapHeaderId == CapId) {
+        if (CapHeaderOffset > PCI_MAXLAT_OFFSET) {
+          ///
+          /// Return valid capability offset
+          ///
+          return CapHeaderOffset;
+        } else {
+          ASSERT ((FALSE));
+          return 0;
+        }
+      }
+      ///
+      /// Each capability must be DWORD aligned.
+      /// The bottom two bits of all pointers (including the initial pointer at 34h) are reserved
+      /// and must be implemented as 00b although software must mask them to allow for future uses of these bits.
+      ///
+      CapHeaderOffset = (UINT8)(Data16 >> 8);
+    }
+    return 0;
+  }
+}
+
+/**
+  Find the Offset to a given Capabilities ID
+  CAPID list:
+    0x01 = PCI Power Management Interface
+    0x04 = Slot Identification
+    0x05 = MSI Capability
+    0x10 = PCI Express Capability
+
+  @param[in] Segment              Pci Segment Number
+  @param[in] Bus                  Pci Bus Number
+  @param[in] Device               Pci Device Number
+  @param[in] Function             Pci Function Number
+  @param[in] CapId                CAPID to search for
+
+  @retval 0                       CAPID not found
+  @retval Other                   CAPID found, Offset of desired CAPID
+**/
+UINT8
+PcieFindCapId (
+  IN UINT8   Segment,
+  IN UINT8   Bus,
+  IN UINT8   Device,
+  IN UINT8   Function,
+  IN UINT8   CapId
+  )
+{
+  UINT64 DeviceBase;
+
+  DeviceBase = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, Function, 0);
+  return PcieBaseFindCapId (DeviceBase, CapId);
+}
+
+/**
+  Search and return the offset of desired Pci Express Capability ID
+  CAPID list:
+    0x0001 = Advanced Error Reporting Capability
+    0x0002 = Virtual Channel Capability
+    0x0003 = Device Serial Number Capability
+    0x0004 = Power Budgeting Capability
+
+  @param[in] DeviceBase           device base address
+  @param[in] CapId                Extended CAPID to search for
+
+  @retval 0                       CAPID not found, this includes situation where device doesn't exist
+  @retval Other                   CAPID found, Offset of desired CAPID
+**/
+UINT16
+PcieBaseFindExtendedCapId (
+  IN UINT64  DeviceBase,
+  IN UINT16  CapId
+  )
+{
+  UINT16  CapHeaderOffset;
+  UINT16  CapHeaderId;
+  ///
+  /// Start to search at Offset 0x100
+  /// Get Capability Header, A pointer value of 00h is used to indicate the last capability in the list.
+  ///
+  CapHeaderId     = 0;
+  CapHeaderOffset = R_PCIE_CFG_EXCAP_OFFSET;
+  while (CapHeaderOffset != 0 && CapHeaderId != MAX_UINT16) {
+    CapHeaderId = PciSegmentRead16 (DeviceBase + CapHeaderOffset);
+    if (CapHeaderId == CapId) {
+      return CapHeaderOffset;
+    }
+    ///
+    /// Each capability must be DWORD aligned.
+    /// The bottom two bits of all pointers are reserved and must be implemented as 00b
+    /// although software must mask them to allow for future uses of these bits.
+    ///
+    CapHeaderOffset = (PciSegmentRead16 (DeviceBase + CapHeaderOffset + 2) >> 4) & ((UINT16) ~(BIT0 | BIT1));
+  }
+
+  return 0;
+}
+
+/**
+  Search and return the offset of desired Pci Express Capability ID
+  CAPID list:
+    0x0001 = Advanced Error Reporting Capability
+    0x0002 = Virtual Channel Capability
+    0x0003 = Device Serial Number Capability
+    0x0004 = Power Budgeting Capability
+
+  @param[in] Segment              Pci Segment Number
+  @param[in] Bus                  Pci Bus Number
+  @param[in] Device               Pci Device Number
+  @param[in] Function             Pci Function Number
+  @param[in] CapId                Extended CAPID to search for
+
+  @retval 0                       CAPID not found, this includes situation where device doesn't exist
+  @retval Other                   CAPID found, Offset of desired CAPID
+**/
+UINT16
+PcieFindExtendedCapId (
+  IN UINT8   Segment,
+  IN UINT8   Bus,
+  IN UINT8   Device,
+  IN UINT8   Function,
+  IN UINT16  CapId
+  )
+{
+  UINT64  DeviceBase;
+
+  DeviceBase = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, Function, 0);
+  return PcieBaseFindExtendedCapId (DeviceBase, CapId);
+}
+
+/**
+  Checks if PCI device at given address exists
+
+  @param[in] Base            device's base address
+
+  @retval TRUE if exists
+**/
+BOOLEAN
+IsDevicePresent (
+  UINT64 Base
+  )
+{
+  if (PciSegmentRead16 (Base) == 0xFFFF) {
+    return FALSE;
+  }
+  return TRUE;
+}
+
+/**
+  Checks if device is a multifunction device
+  Besides comparing Multifunction bit (BIT7) it checks if contents of HEADER_TYPE register
+  make sense (header != 0xFF) to prevent false positives when called on devices which do not exist
+
+  @param[in] Base            device's base address
+
+  @retval TRUE if multifunction; FALSE otherwise
+**/
+BOOLEAN
+IsMultifunctionDevice (
+  UINT64 Base
+  )
+{
+  UINT8 HeaderType;
+  HeaderType = PciSegmentRead8(Base + PCI_HEADER_TYPE_OFFSET);
+  if ((HeaderType == 0xFF) || ((HeaderType & HEADER_TYPE_MULTI_FUNCTION) == 0)) {
+    return FALSE;
+  }
+  return TRUE;
+}
+
+/**
+  Checks device's Slot Clock Configuration
+
+  @param[in] Base            device's base address
+  @param[in] PcieCapOffset   devices Pci express capability list register offset
+
+  @retval TRUE when device uses slot clock, FALSE otherwise
+**/
+BOOLEAN
+GetScc (
+  UINT64    Base,
+  UINT8     PcieCapOffset
+  )
+{
+  return !!(PciSegmentRead16 (Base + PcieCapOffset + R_PCIE_LSTS_OFFSET) & B_PCIE_LSTS_SCC);
+}
+
+/**
+  Sets Common Clock Configuration bit for given device.
+
+  @param[in] PcieCapOffset   devices Pci express capability list register offset
+  @param[in] Base            device's base address
+**/
+VOID
+EnableCcc (
+  UINT64    Base,
+  UINT8     PcieCapOffset
+  )
+{
+  PciSegmentOr8 (Base + PcieCapOffset + R_PCIE_LCTL_OFFSET, B_PCIE_LCTL_CCC);
+}
+
+/**
+  Retrains link behind given device.
+  It only makes sense to call it for downstream ports. If called for upstream port nothing will happen.
+  If WaitUntilDone is TRUE function will wait until link retrain had finished, otherwise it will return immediately.
+  Link must finish retrain before software can access the device on the other side. If it's not going to access it
+  then considerable time can be saved by not waiting here.
+
+  @param[in] Base             device's base address
+  @param[in] PcieCapOffset    devices Pci express capability list register offset
+  @param[in] WaitUntilDone    when TRUE, function waits until link has retrained
+**/
+VOID
+RetrainLink (
+  UINT64  Base,
+  UINT8   PcieCapOffset,
+  BOOLEAN WaitUntilDone
+  )
+{
+  UINT16 LinkTraining;
+  UINT32 TimeoutUs;
+
+  TimeoutUs = LINK_RETRAIN_WAIT_TIME;
+  //
+  // Before triggering link retrain make sure it's not already retraining. Otherwise
+  // settings recently entered in LCTL register might go unnoticed
+  //
+  do {
+    LinkTraining = (PciSegmentRead16 (Base + PcieCapOffset + R_PCIE_LSTS_OFFSET) & B_PCIE_LSTS_LT);
+    TimeoutUs--;
+  } while (LinkTraining && (TimeoutUs != 0));
+
+  PciSegmentOr8 (Base + PcieCapOffset + R_PCIE_LCTL_OFFSET, B_PCIE_LCTL_RL);
+
+  TimeoutUs = LINK_RETRAIN_WAIT_TIME;
+  if (WaitUntilDone) {
+    do {
+      LinkTraining = (PciSegmentRead16 (Base + PcieCapOffset + R_PCIE_LSTS_OFFSET) & B_PCIE_LSTS_LT);
+      TimeoutUs--;
+    } while (LinkTraining && (TimeoutUs != 0));
+  }
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/Library/BasePcieHelperLib/BasePcieHelperLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/Library/BasePcieHelperLib/BasePcieHelperLib.inf
new file mode 100644
index 0000000000..458a540859
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/Library/BasePcieHelperLib/BasePcieHelperLib.inf
@@ -0,0 +1,37 @@
+## @file
+# Component description file for the BasePcieHelperLib
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = BasePcieHelperLib
+FILE_GUID = 568F5812-A9A8-4A4A-AD4D-471DD5F0BC11
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = BasePcieHelperLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+
+
+[LibraryClasses]
+DebugLib
+PciSegmentLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+BasePcieHelperLib.c
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/Library/PeiDxeSmmPchPcieRpLib/PchPcieRpLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/Library/PeiDxeSmmPchPcieRpLib/PchPcieRpLib.c
new file mode 100644
index 0000000000..153c073093
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/Library/PeiDxeSmmPchPcieRpLib/PchPcieRpLib.c
@@ -0,0 +1,69 @@
+/** @file
+  PCIE root port library.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchPcieRpLib.h>
+#include <PcieRegs.h>
+#include <Register/PchRegs.h>
+#include <PchPcieRpInfo.h>
+#include <Register/PchPcieRpRegs.h>
+#include <Register/PchPcrRegs.h>
+#include <Library/PchPciBdfLib.h>
+
+#include "PchPcieRpLibInternal.h"
+
+/**
+  Gets pci segment base address of PCIe root port.
+
+  @param RpIndex    Root Port Index (0 based)
+  @return PCIe port base address.
+**/
+UINT64
+PchPcieBase (
+  IN  UINT32   RpIndex
+  )
+{
+  return PchPcieRpPciCfgBase (RpIndex);
+}
+
+/**
+  Determines whether L0s is supported on current stepping.
+
+  @return TRUE if L0s is supported, FALSE otherwise
+**/
+BOOLEAN
+PchIsPcieL0sSupported (
+  VOID
+  )
+{
+  return TRUE;
+}
+
+/**
+  Some early PCH steppings require Native ASPM to be disabled due to hardware issues:
+   - RxL0s exit causes recovery
+   - Disabling PCIe L0s capability disables L1
+  Use this function to determine affected steppings.
+
+  @return TRUE if Native ASPM is supported, FALSE otherwise
+**/
+BOOLEAN
+PchIsPcieNativeAspmSupported (
+  VOID
+  )
+{
+  return PchIsPcieL0sSupported ();
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/Library/PeiDxeSmmPchPcieRpLib/PchPcieRpLibInternal.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/Library/PeiDxeSmmPchPcieRpLib/PchPcieRpLibInternal.h
new file mode 100644
index 0000000000..1766cff618
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/Library/PeiDxeSmmPchPcieRpLib/PchPcieRpLibInternal.h
@@ -0,0 +1,20 @@
+/** @file
+  PCIE root port library.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_PCIE_RP_LIB_INTERNAL_H_
+#define _PCH_PCIE_RP_LIB_INTERNAL_H_
+
+typedef struct {
+  UINT8 DevNum;
+  UINT8 Pid;
+  UINT8 RpNumBase;
+} PCH_PCIE_CONTROLLER_INFO;
+
+#endif
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/Library/PeiDxeSmmPchPcieRpLib/PchPcieRpLibVer2.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/Library/PeiDxeSmmPchPcieRpLib/PchPcieRpLibVer2.c
new file mode 100644
index 0000000000..df90a87df7
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/Library/PeiDxeSmmPchPcieRpLib/PchPcieRpLibVer2.c
@@ -0,0 +1,128 @@
+/** @file
+  PCIE root port library.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchPcieRpLib.h>
+#include <PcieRegs.h>
+#include <Register/PchRegs.h>
+#include <PchBdfAssignment.h>
+#include <PchPcieRpInfo.h>
+#include <Register/PchPcieRpRegs.h>
+#include <Register/PchPcrRegs.h>
+
+#include "PchPcieRpLibInternal.h"
+
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_PCIE_CONTROLLER_INFO mPchPcieControllerInfo[] = {
+  { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_1,  PID_SPA,  0 },
+  { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_5,  PID_SPB,  4 },
+  { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_9,  PID_SPC,  8 },
+  { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_13, PID_SPD, 12 },
+  { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_17, PID_SPE, 16 }, // PCH-H only
+  { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_21, PID_SPF, 20 }  // PCH-H only
+};
+
+/**
+  Get Pch Pcie Root Port Device and Function Number by Root Port physical Number
+
+  @param[in]  RpNumber              Root port physical number. (0-based)
+  @param[out] RpDev                 Return corresponding root port device number.
+  @param[out] RpFun                 Return corresponding root port function number.
+
+  @retval     EFI_SUCCESS           Root port device and function is retrieved
+  @retval     EFI_INVALID_PARAMETER RpNumber is invalid
+**/
+EFI_STATUS
+EFIAPI
+GetPchPcieRpDevFun (
+  IN  UINTN   RpNumber,
+  OUT UINTN   *RpDev,
+  OUT UINTN   *RpFun
+  )
+{
+  UINTN       Index;
+  UINTN       FuncIndex;
+  UINT32      PciePcd;
+
+  if (RpNumber >= GetPchMaxPciePortNum ()) {
+    DEBUG ((DEBUG_ERROR, "GetPchPcieRpDevFun invalid RpNumber %x", RpNumber));
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Index = RpNumber / PCH_PCIE_CONTROLLER_PORTS;
+  FuncIndex = RpNumber - mPchPcieControllerInfo[Index].RpNumBase;
+  *RpDev = mPchPcieControllerInfo[Index].DevNum;
+  PciePcd = PchPcrRead32 (mPchPcieControllerInfo[Index].Pid, R_SPX_PCR_PCD);
+  *RpFun = (PciePcd >> (FuncIndex * S_SPX_PCR_PCD_RP_FIELD)) & B_SPX_PCR_PCD_RP1FN;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Get Root Port physical Number by Pch Pcie Root Port Device and Function Number
+
+  @param[in]  RpDev                 Root port device number.
+  @param[in]  RpFun                 Root port function number.
+  @param[out] RpNumber              Return corresponding physical Root Port index (0-based)
+
+  @retval     EFI_SUCCESS           Physical root port is retrieved
+**/
+EFI_STATUS
+EFIAPI
+GetPchPcieRpNumber (
+  IN  UINTN   RpDev,
+  IN  UINTN   RpFun,
+  OUT UINTN   *RpNumber
+  )
+{
+  UINT64 RpBase;
+
+  RpBase = PCI_SEGMENT_LIB_ADDRESS (DEFAULT_PCI_SEGMENT_NUMBER_PCH, DEFAULT_PCI_BUS_NUMBER_PCH, RpDev, RpFun, 0);
+  *RpNumber = (PciSegmentRead32 (RpBase + R_PCH_PCIE_CFG_LCAP) >> N_PCH_PCIE_CFG_LCAP_PN) -1;
+  return EFI_SUCCESS;
+}
+
+/**
+  This function returns PID according to PCIe controller index
+
+  @param[in] ControllerIndex     PCIe controller index
+
+  @retval PCH_SBI_PID    Returns PID for SBI Access
+**/
+PCH_SBI_PID
+PchGetPcieControllerSbiPid (
+  IN UINT32  ControllerIndex
+  )
+{
+  ASSERT (ControllerIndex < ARRAY_SIZE (mPchPcieControllerInfo));
+  return mPchPcieControllerInfo[ControllerIndex].Pid;
+}
+
+/**
+  This function returns PID according to Root Port Number
+
+  @param[in] RpIndex     Root Port Index (0-based)
+
+  @retval PCH_SBI_PID    Returns PID for SBI Access
+**/
+PCH_SBI_PID
+GetRpSbiPid (
+  IN UINTN  RpIndex
+  )
+{
+  return PchGetPcieControllerSbiPid ((UINT32) (RpIndex / PCH_PCIE_CONTROLLER_PORTS));
+}
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/Library/PeiDxeSmmPchPcieRpLib/PeiDxeSmmPchPcieRpLibVer2.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/Library/PeiDxeSmmPchPcieRpLib/PeiDxeSmmPchPcieRpLibVer2.inf
new file mode 100644
index 0000000000..4fc217581b
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/Library/PeiDxeSmmPchPcieRpLib/PeiDxeSmmPchPcieRpLibVer2.inf
@@ -0,0 +1,39 @@
+## @file
+# PCIE root port Library.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchPcieRpLib
+FILE_GUID = B522981C-E0C5-4E04-A82A-C61D4F0B2C75
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchPcieRpLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PciSegmentLib
+PchInfoLib
+PchPcrLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchPcieRpLib.c
+PchPcieRpLibVer2.c
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/DxePchPcieRpPolicyLib/DxePchPcieRpPolicyLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/DxePchPcieRpPolicyLib/DxePchPcieRpPolicyLib.c
new file mode 100644
index 0000000000..577e436e32
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/DxePchPcieRpPolicyLib/DxePchPcieRpPolicyLib.c
@@ -0,0 +1,179 @@
+/** @file
+  This file provides services for PcieRp policy function
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/SiConfigBlockLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Protocol/PchPolicy.h>
+#include <PchPcieRpConfig.h>
+
+#define PCI_CLASS_NETWORK             0x02
+#define PCI_CLASS_NETWORK_ETHERNET    0x00
+#define PCI_CLASS_NETWORK_OTHER       0x80
+
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_PCIE_DEVICE_OVERRIDE mPcieDeviceTable[] = {
+  //
+  // Intel PRO/Wireless
+  //
+  { 0x8086, 0x422b, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  { 0x8086, 0x422c, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  { 0x8086, 0x4238, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  { 0x8086, 0x4239, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  //
+  // Intel WiMAX/WiFi Link
+  //
+  { 0x8086, 0x0082, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  { 0x8086, 0x0085, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  { 0x8086, 0x0083, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  { 0x8086, 0x0084, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  { 0x8086, 0x0086, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  { 0x8086, 0x0087, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  { 0x8086, 0x0088, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  { 0x8086, 0x0089, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  { 0x8086, 0x008F, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  { 0x8086, 0x0090, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  //
+  // Intel Crane Peak WLAN NIC
+  //
+  { 0x8086, 0x08AE, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  { 0x8086, 0x08AF, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  //
+  // Intel Crane Peak w/BT WLAN NIC
+  //
+  { 0x8086, 0x0896, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  { 0x8086, 0x0897, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  //
+  // Intel Kelsey Peak WiFi, WiMax
+  //
+  { 0x8086, 0x0885, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  { 0x8086, 0x0886, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  //
+  // Intel Centrino Wireless-N 105
+  //
+  { 0x8086, 0x0894, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  { 0x8086, 0x0895, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  //
+  // Intel Centrino Wireless-N 135
+  //
+  { 0x8086, 0x0892, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  { 0x8086, 0x0893, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  //
+  // Intel Centrino Wireless-N 2200
+  //
+  { 0x8086, 0x0890, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  { 0x8086, 0x0891, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  //
+  // Intel Centrino Wireless-N 2230
+  //
+  { 0x8086, 0x0887, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  { 0x8086, 0x0888, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  //
+  // Intel Centrino Wireless-N 6235
+  //
+  { 0x8086, 0x088E, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  { 0x8086, 0x088F, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  //
+  // Intel CampPeak 2 Wifi
+  //
+  { 0x8086, 0x08B5, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  { 0x8086, 0x08B6, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  //
+  // Intel WilkinsPeak 1 Wifi
+  //
+  { 0x8086, 0x08B3, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2AndL1SubstatesOverride, 0x0158, 0x0000000F, 0, 0, 0, 0, 0 },
+  { 0x8086, 0x08B4, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2AndL1SubstatesOverride, 0x0158, 0x0000000F, 0, 0, 0, 0, 0 },
+  //
+  // Intel Wilkins Peak 2 Wifi
+  //
+  { 0x8086, 0x08B1, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2AndL1SubstatesOverride, 0x0158, 0x0000000F, 0, 0, 0, 0, 0 },
+  { 0x8086, 0x08B2, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2AndL1SubstatesOverride, 0x0158, 0x0000000F, 0, 0, 0, 0, 0 },
+  //
+  // Intel Wilkins Peak PF Wifi
+  //
+  { 0x8086, 0x08B0, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0, 0, 0, 0, 0, 0, 0 },
+  //
+  // Teton Glacier Endpoint
+  //
+  { 0x8086, 0x0975, 0xff, 0, 0, 0, PchPcieL1SubstatesOverride, 0, 0xff, 0x3C, 0, 5, 0, 0, 0, 0 },
+
+  //
+  // End of Table
+  //
+  { 0 }
+};
+
+/**
+  Print PCIE_RP_DXE_CONFIG.
+
+  @param[in] PchPolicy            Pointer to a PCH_POLICY_PROTOCOL
+**/
+VOID
+PchPcieRpDxePrintConfig (
+  IN PCH_POLICY_PROTOCOL    *PchPolicy
+  )
+{
+  EFI_STATUS            Status;
+  PCIE_RP_DXE_CONFIG    *PchPcieRpDxeConfig;
+
+  Status = GetConfigBlock ((VOID *) PchPolicy, &gPchPcieRpDxeConfigGuid, (VOID *) &PchPcieRpDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "------------------ PCH PCIE DXE CONFIG ------------------\n"));
+  DEBUG ((DEBUG_INFO, " PcieDeviceOverrideTablePtr : 0x%x\n",PchPcieRpDxeConfig->PcieDeviceOverrideTablePtr));
+}
+
+/**
+  Load DXE Config block default for Pch PCIE RP
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadPchPcieRpDxeConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  PCIE_RP_DXE_CONFIG  *PchPcieRpDxeConfig;
+
+  PchPcieRpDxeConfig = ConfigBlockPointer;
+  PchPcieRpDxeConfig->PcieDeviceOverrideTablePtr = mPcieDeviceTable;
+}
+
+STATIC COMPONENT_BLOCK_ENTRY  mPchPcieRpBlocks = {
+  &gPchPcieRpDxeConfigGuid,
+  sizeof (PCIE_RP_DXE_CONFIG),
+  PCIE_RP_DXE_CONFIG_REVISION,
+  LoadPchPcieRpDxeConfigDefault
+};
+
+/**
+  Get PchPcieRp config block table size.
+
+  @retval      Size of config block
+**/
+UINT16
+PchPcieRpDxeGetConfigBlockTotalSize (
+  VOID
+  )
+{
+  return mPchPcieRpBlocks.Size;
+}
+
+/**
+  Add PchPcieRp ConfigBlock.
+
+  @param[in] ConfigBlockTableAddress    The pointer to config block table
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+PchPcieRpDxeAddConfigBlock (
+  IN VOID           *ConfigBlockTableAddress
+  )
+{
+  return AddComponentConfigBlocks (ConfigBlockTableAddress, &mPchPcieRpBlocks, 1);
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/DxePchPcieRpPolicyLib/DxePchPcieRpPolicyLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/DxePchPcieRpPolicyLib/DxePchPcieRpPolicyLib.inf
new file mode 100644
index 0000000000..6158e77a35
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/DxePchPcieRpPolicyLib/DxePchPcieRpPolicyLib.inf
@@ -0,0 +1,30 @@
+## @file
+# Component description file for the PchPcieRp policy library
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxePchPcieRpPolicyLib
+FILE_GUID = 328B0DE5-189A-4DB0-BFE1-557F4F89010B
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = DxePchPcieRpPolicyLib
+
+[LibraryClasses]
+DebugLib
+ConfigBlockLib
+SiConfigBlockLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Sources]
+DxePchPcieRpPolicyLib.c
+
+[Guids]
+gPchPcieRpDxeConfigGuid  ## CONSUMES
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/PciExpressHelpersLibrary/PciExpressHelpersLibrary.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/PciExpressHelpersLibrary/PciExpressHelpersLibrary.c
new file mode 100644
index 0000000000..401a9fbe7b
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/PciExpressHelpersLibrary/PciExpressHelpersLibrary.c
@@ -0,0 +1,1997 @@
+/** @file
+  This file contains routines that support PCI Express initialization
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "PciExpressHelpersLibrary.h"
+#include <Library/BaseMemoryLib.h>
+#include <Library/PcieHelperLib.h>
+#include <Library/PchPciBdfLib.h>
+#include <Library/PcieRpLib.h>
+#include <PchPcieRpInfo.h>
+#include <CpuPcieInfo.h>
+#include <CpuPcieHob.h>
+#include <Library/HobLib.h>
+#include <Register/PchPcieRpRegs.h>
+
+#define ASPM_L1_NO_LIMIT 0xFF
+#define ASPM_L0s_NO_LIMIT 0x7
+#define LINK_RETRAIN_WAIT_TIME 1000 // microseconds
+
+typedef union {
+  struct {
+    UINT32  RequesterCapable       : 1;
+    UINT32  ResponderCapable       : 1;
+    UINT32  RootCapable            : 1;
+    UINT32  Reserved               : 5;
+    UINT32  LocalClockGranularity  : 8;
+    UINT32  Reserved2              : 16;
+  } Bits;
+  UINT32  Uint32;
+} PTM_CAPS;
+
+typedef union {
+  struct {
+    UINT32 Enable                 : 1;
+    UINT32 RootSelect             : 1;
+    UINT32 Reserved               : 6;
+    UINT32 EffectiveGranularity   : 8;
+    UINT32 Reserved2              : 16;
+  } Bits;
+  UINT32  Uint32;
+} PTM_CTRL;
+
+typedef struct {
+  UINT32                          Size;
+  const PCH_PCIE_DEVICE_OVERRIDE* Table;
+} OVERRIDE_TABLE;
+
+typedef enum {
+  DevTypePci,
+  DevTypePcieEndpoint,
+  DevTypePcieUpstream,
+  DevTypePcieDownstream,
+  DevTypeMax
+} PCI_DEV_TYPE;
+
+//
+// This structure keeps in one place all data relevant to enabling L0s and L1.
+// L0s latencies are encoded in the same way as in hardware registers. The only operation
+// that will be performed on them is comparison
+// L1 latencies are decoded to microseconds, because they will be used in subtractions and additions
+//
+typedef struct {
+  UINT32  L0sSupported          : 1;
+  UINT32  L1Supported           : 1;
+  UINT32  L0sAcceptableLatency  : 3; // encoded as in hardware register
+  UINT32  L1AcceptableLatencyUs : 8; // decoded to microseconds
+  UINT32  LinkL0sExitLatency    : 3; // encoded as in hardware register
+  UINT32  LinkL1ExitLatencyUs   : 8; // decoded to microseconds
+} ASPM_CAPS;
+
+typedef struct {
+  UINT32     AspmL11  : 1;
+  UINT32     AspmL12  : 1;
+  UINT32     PmL11    : 1;
+  UINT32     PmL12    : 1;
+  UINT32     Cmrt     : 8; // Common Mode Restore Time
+  UINT32     TpoScale : 2; // T power_on scale
+  UINT32     TpoValue : 6; // T power_on value
+} L1SS_CAPS;
+
+#define MAX_SBDF_TABLE_SIZE 50 //arbitrary table size; big enough to accomodate even full length TBT chain.
+
+typedef struct {
+  UINT32 Count;
+  SBDF   Entry [MAX_SBDF_TABLE_SIZE];
+} SBDF_TABLE;
+
+/**
+  Converts device's segment:bus:device:function coordinates to flat address
+
+  @param[in] Sbdf   device's segment:bus:device:function coordinates
+
+  @retval    address of device's PCI cfg space
+**/
+STATIC
+UINT64
+SbdfToBase (
+  SBDF Sbdf
+  )
+{
+  return PCI_SEGMENT_LIB_ADDRESS (Sbdf.Seg, Sbdf.Bus, Sbdf.Dev, Sbdf.Func, 0);
+}
+
+/*
+  Converts Tpower_on from value:scale notation to microseconds
+
+  @param[in] TpoScale   T power on scale
+  @param[in] TpoValue   T power on value
+
+  @retval    number of microseconds
+*/
+UINT32
+TpoToUs (
+  UINT32 TpoScale,
+  UINT32 TpoValue
+  )
+{
+  static const UINT8 TpoScaleMultiplier[] = {2, 10, 100};
+
+  ASSERT (TpoScale < TpoScaleMax);
+  if (TpoScale >= TpoScaleMax) {
+    return 0;
+  }
+  return (TpoScaleMultiplier[TpoScale] * TpoValue);
+}
+
+/**
+  Get max payload size supported by device.
+
+  @param[in] Sbdf   device's segment:bus:device:function coordinates
+
+  @retval    Max payload size, encoded in the same way as in register (0=128b, 1=256b, etc)
+**/
+STATIC
+UINT8
+GetMps (
+  SBDF Sbdf
+  )
+{
+  return (PciSegmentRead16 (SbdfToBase (Sbdf) + Sbdf.PcieCap + R_PCIE_DCAP_OFFSET) & B_PCIE_DCAP_MPS);
+}
+
+/**
+  Sets Maximum Payload Size to be used by device
+
+  @param[in] Sbdf   device's segment:bus:device:function coordinates
+  @param[in] Mps    Max payload size, encoded in the same way as in register (0=128b, 1=256b, etc)
+**/
+STATIC
+VOID
+SetMps (
+  SBDF  Sbdf,
+  UINT8  Mps
+  )
+{
+  PciSegmentAndThenOr16 (SbdfToBase (Sbdf) + Sbdf.PcieCap + R_PCIE_DCTL_OFFSET, (UINT16) ~B_PCIE_DCTL_MPS, Mps << N_PCIE_DCTL_MPS);
+}
+
+/**
+  Enables LTR feature in given device
+
+  @param[in] Sbdf            device's segment:bus:device:function coordinates
+**/
+STATIC
+VOID
+EnableLtr (
+  SBDF Sbdf
+  )
+{
+  if (Sbdf.PcieCap == 0) {
+    return;
+  }
+  PciSegmentOr32 (SbdfToBase (Sbdf) + Sbdf.PcieCap + R_PCIE_DCTL2_OFFSET, B_PCIE_DCTL2_LTREN);
+}
+
+/**
+  Returns information about type of device.
+
+  @param[out] Sbdf            device's segment:bus:device:function coordinates
+
+  @retval     one of: not a PCIe device (legacy PCI), PCIe endpoint, PCIe upstream port or PCIe downstream port (including rootport)
+**/
+STATIC
+PCI_DEV_TYPE
+GetDeviceType (
+  SBDF Sbdf
+  )
+{
+  UINT8 DeviceType;
+
+  if (Sbdf.PcieCap == 0) {
+    return DevTypePci;
+  }
+  DeviceType = (UINT8) ((PciSegmentRead16 (SbdfToBase (Sbdf) + Sbdf.PcieCap + R_PCIE_XCAP_OFFSET) & B_PCIE_XCAP_DT) >> N_PCIE_XCAP_DT);
+  if (DeviceType == PCIE_DEVICE_PORT_TYPE_UPSTREAM_PORT) {
+    return DevTypePcieUpstream;
+  } else if (DeviceType == PCIE_DEVICE_PORT_TYPE_DOWNSTREAM_PORT || DeviceType == PCIE_DEVICE_PORT_TYPE_ROOT_PORT) {
+    return DevTypePcieDownstream;
+  } else {
+    return DevTypePcieEndpoint;
+  }
+}
+
+/**
+  Initializes Dev:Func numbers for use in FindNextPcieChild or FindNextLegalSbdf functions.
+
+  @param[out] Sbdf            device's segment:bus:device:function coordinates
+**/
+STATIC
+VOID
+InitChildFinder (
+  OUT SBDF *Sbdf
+  )
+{
+  //
+  // Initialize Dev/Func to maximum values, so that when FindNextLegalSbdf ()
+  // is called on those input parameters, it will return 1st legal address (Dev 0 Func 0).
+  //
+  Sbdf->Dev = PCI_MAX_DEVICE;
+  Sbdf->Func = PCI_MAX_FUNC;
+}
+
+/**
+  Checks the device is a bridge and has non-zero secondary bus number assigned.
+  If so, it returns TRUE and initializes ChildSbdf with such values that
+  allow searching for devices on the secondary bus.
+  ChildSbdf will be mangled even if this function returns FALSE.
+
+  Legal bus assignment is assumed. This function doesn't check subordinate bus numbers of
+  the the device it was called on or any bridges between it and root complex
+
+  @param[in]  Sbdf       device's segment:bus:device:function coordinates
+  @param[out] ChildSbdf  SBDF initialized in such way that calling FindNextPcieChild( ) on it will find all children devices
+
+  @retval TRUE if device is a bridge and has a bus behind it; FALSE otherwise
+**/
+STATIC
+BOOLEAN
+HasChildBus (
+  SBDF   Sbdf,
+  SBDF   *ChildSbdf
+  )
+{
+  UINT32 Data32;
+  UINT64 Base;
+  UINT8  SecondaryBus;
+
+  ChildSbdf->Seg = Sbdf.Seg;
+  InitChildFinder (ChildSbdf);
+
+  Base = SbdfToBase (Sbdf);
+
+  if (PciSegmentRead8 (Base + R_PCI_BCC_OFFSET) != PCI_CLASS_BRIDGE) {
+    DEBUG ((DEBUG_INFO, "HasChildBus%02:%02:%02: no\n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func));
+    return FALSE;
+  }
+  Data32 = PciSegmentRead32 (Base + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET);
+  SecondaryBus = (UINT8)((Data32 & B_PCI_BRIDGE_BNUM_SCBN) >> 8);
+  ChildSbdf->Bus = SecondaryBus;
+  if (SecondaryBus == 0) {
+    DEBUG ((DEBUG_INFO, "HasChildBus%02x:%02x:%02x: no\n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func));
+    return FALSE;
+  } else {
+    DEBUG ((DEBUG_INFO, "HasChildBus%02x:%02x:%02x: yes, %x\n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func, SecondaryBus));
+    return TRUE;
+  }
+}
+
+/**
+  Sets LTR limit in a device.
+
+  @param[in] Base            device's base address
+  @param[in] Ltr             LTR limit
+**/
+STATIC
+VOID
+SetLtrLimit (
+  UINT64    Base,
+  LTR_LIMIT Ltr
+  )
+{
+  UINT16 LtrCapOffset;
+  UINT16 Data16;
+
+  LtrCapOffset = PcieBaseFindExtendedCapId (Base, R_PCIE_LTRECH_CID);
+  if (LtrCapOffset == 0) {
+    return;
+  }
+  Data16 = (UINT16)((Ltr.MaxSnoopLatencyValue << N_PCIE_LTRECH_MSLR_VALUE) | (Ltr.MaxSnoopLatencyScale << N_PCIE_LTRECH_MSLR_SCALE));
+  PciSegmentWrite16(Base + LtrCapOffset + R_PCIE_LTRECH_MSLR_OFFSET, Data16);
+
+  Data16 = (UINT16)((Ltr.MaxNoSnoopLatencyValue << N_PCIE_LTRECH_MNSLR_VALUE) | (Ltr.MaxNoSnoopLatencyScale << N_PCIE_LTRECH_MNSLR_SCALE));
+  PciSegmentWrite16(Base + LtrCapOffset + R_PCIE_LTRECH_MNSLR_OFFSET, Data16);
+}
+
+/**
+  Checks if device at given address exists and is a PCI Express device.
+  PCI express devices are distinguished from PCI by having Capability ID 0x10
+  If the device is PCI express then its SDBF structure gets updated with pointer to
+  the PCIe Capability. This is an optimization feature. It greatly decreases the number
+  of bus accesses, since most features configured by this library depend on registers
+  whose location is relative to PCIe capability.
+
+  @param[in,out] Sbdf   on entry, segment:bus:device:function coordinates
+                        on exit, PcieCap offset is updated
+
+  @retval               TRUE when PCIe device exists; FALSE if it's not PCIe or there's no device at all
+**/
+STATIC
+BOOLEAN
+IsPcieDevice (
+  SBDF *Sbdf
+  )
+{
+  UINT8 PcieCapOffset;
+  UINT64         Base;
+
+  Base = SbdfToBase(*Sbdf);
+
+  if (PciSegmentRead16 (Base) == 0xFFFF) {
+    return FALSE;
+  }
+
+
+  PcieCapOffset = PcieBaseFindCapId (Base, EFI_PCI_CAPABILITY_ID_PCIEXP);
+  if (PcieCapOffset == 0) {
+    DEBUG ((DEBUG_INFO, "IsPcieDevice %02x:%02x:%02x - legacy\n", Sbdf->Bus, Sbdf->Dev, Sbdf->Func));
+    return FALSE;
+  } else {
+    Sbdf->PcieCap = PcieCapOffset;
+    DEBUG ((DEBUG_INFO, "IsPcieDevice %02x:%02x:%02x - yes\n", Sbdf->Bus, Sbdf->Dev, Sbdf->Func));
+    return TRUE;
+  }
+}
+
+/**
+  Returns TRUE and Dev:Func numbers where a PCIe device could legally be located, or FALSE if there
+  no such coordinates left.
+
+  Segment and Bus fields of SBDF structure are input only and determine which bus will be scanned.
+  This function should be called in a while() loop. It replaces the less efficient method of
+  using nested FOR loops that iterate over all device and function numbers. It is optimized for
+  the amount of bus access. If function0 doesn't exist or doesn't have Multifunction bit set,
+  then higher function numbers are skipped. If parent of this bus is a downstream port, then
+  Device numbers 1-31 get skipped too (there can be only Dev0 behind downstream ports)
+  If device/function number == 0x1F/0x7, this function returns first possible address, that is 0:0
+  Any other device number means Dev:Func contain address of last found child device
+  and this function should search for next one
+
+  @param[in]     ParentDevType  type of bridge who's partent of this bus
+  @param[in,out] Sbdf           On entry: location returned previously from this function
+                                          Dev:Func value of 1F:07 means search should start from the beginning
+                                On exit:  if legal Dev:Func combination was found, that Dev:Func is returned
+                                          otherwise, Dev:Func are initialized to 1F:07 for convenience
+
+  @retval TRUE when next legal Dev:Func address was found; FALSE otherwise
+**/
+STATIC
+BOOLEAN
+FindNextLegalSbdf (
+  IN     PCI_DEV_TYPE ParentDevType,
+  IN OUT SBDF         *Sbdf
+  )
+{
+  UINT8  MaxDev;
+  UINT64 Func0Base;
+
+  if (ParentDevType == DevTypePcieEndpoint) {
+    return FALSE;
+  }
+  if (ParentDevType == DevTypePcieUpstream) {
+    MaxDev = PCI_MAX_DEVICE;
+  } else {
+    MaxDev = 0;
+  }
+  Func0Base = PCI_SEGMENT_LIB_ADDRESS (Sbdf->Seg, Sbdf->Bus, Sbdf->Dev, 0, 0);
+  if ((Sbdf->Dev == PCI_MAX_DEVICE) && Sbdf->Func == PCI_MAX_FUNC) {
+    Sbdf->Dev = 0;
+    Sbdf->Func = 0;
+    return TRUE;
+  } else if ((Sbdf->Func == PCI_MAX_FUNC) || (Sbdf->Func == 0 && !IsMultifunctionDevice (Func0Base))) {
+  //
+  // if it's the last function of a device, then return Func0 of new device or FALSE in case there are no more devices
+  //
+    if (Sbdf->Dev == MaxDev) {
+      InitChildFinder (Sbdf);
+      return FALSE;
+    }
+    (Sbdf->Dev)++;
+    Sbdf->Func = 0;
+    return TRUE;
+  } else {
+    (Sbdf->Func)++;
+    return TRUE;
+  }
+}
+
+/**
+  Finds next PCIe (not legacy PCI) device behind given device
+  If device/function number == 0x1F/0x7, this function searches for children from scratch
+  Any other device number means Dev:Func contain address of last found child device
+  and this function should search for next one
+
+  @param[in]     ParentDevType  type of bridge who's partent of this bus
+  @param[in,out] Sbdf           On entry: location returned previously from this function
+                                          Dev:Func value of 0x1F:0x07 means search should start from the beginning
+                                On exit:  if PCIe device was found, its SBDF coordinates are returned
+                                          otherwise, Dev:Func are initialized to 0x1F:0x07 for convenience
+  @retval TRUE when next PCIe device was found; FALSE otherwise
+**/
+BOOLEAN
+FindNextPcieChild (
+  IN     PCI_DEV_TYPE ParentDevType,
+  IN OUT SBDF   *Sbdf
+  )
+{
+  while ( FindNextLegalSbdf (ParentDevType, Sbdf)) {
+    if (IsPcieDevice (Sbdf)) {
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+/**
+  Checks if given device supports Clock Power Management
+
+  @param[in] Sbdf     segment:bus:device:function coordinates of a device
+
+  @retval TRUE when device supports it, FALSE otherwise
+**/
+STATIC
+BOOLEAN
+IsCpmSupported (
+  SBDF Sbdf
+  )
+{
+  return !!(PciSegmentRead32 (SbdfToBase (Sbdf) + Sbdf.PcieCap + R_PCIE_LCAP_OFFSET) & B_PCIE_LCAP_CPM);
+}
+
+/**
+  Sets Enable Clock Power Management bit for given device
+
+  @param[in] Sbdf            segment:bus:device:function coordinates of a device
+**/
+STATIC
+VOID
+EnableCpm (
+  SBDF Sbdf
+  )
+{
+  PciSegmentOr16 (SbdfToBase (Sbdf) + Sbdf.PcieCap + R_PCIE_LCTL_OFFSET, B_PCIE_LCTL_ECPM);
+}
+
+/**
+  Checks if given device is an IoAPIC
+
+  @param[in] Base            device's base address
+
+  @retval TRUE if it's an IoAPIC
+**/
+BOOLEAN
+IsIoApicDevice (
+  UINT64 Base
+  )
+{
+  UINT8 BaseClassCode;
+  UINT8 SubClassCode;
+  UINT8 ProgInterface;
+
+  BaseClassCode = PciSegmentRead8 (Base + PCI_CLASSCODE_OFFSET + 2);
+  SubClassCode  = PciSegmentRead8 (Base + PCI_CLASSCODE_OFFSET + 1);
+  ProgInterface = PciSegmentRead8 (Base + PCI_CLASSCODE_OFFSET);
+  if ((BaseClassCode == PCI_CLASS_SYSTEM_PERIPHERAL) &&
+      (SubClassCode == PCI_SUBCLASS_PIC) &&
+      ((ProgInterface == PCI_IF_APIC_CONTROLLER) ||
+       (ProgInterface == PCI_IF_APIC_CONTROLLER2))) {
+    return TRUE;
+  }
+  return FALSE;
+}
+
+/**
+  There are some devices which support L1 substates, but due to silicon bugs the corresponding register
+  cannot be found by scanning PCIe capabilities. This function checks list of such devices and if one
+  is found, returns its L1ss capability register offset
+
+  @param[in] Base       base address of device
+  @param[in] Override   table of devices that need override
+
+  @retval               offset to L1ss capability register
+**/
+UINT16
+GetOverrideL1ssCapsOffset (
+  UINT64         Base,
+  OVERRIDE_TABLE *Override
+  )
+{
+  UINT16 DeviceId;
+  UINT16 VendorId;
+  UINT8  Revision;
+  UINT32 Index;
+
+  VendorId = PciSegmentRead16 (Base + PCI_VENDOR_ID_OFFSET);
+  DeviceId = PciSegmentRead16 (Base + PCI_DEVICE_ID_OFFSET);
+  Revision = PciSegmentRead8  (Base + PCI_REVISION_ID_OFFSET);
+
+  for (Index = 0; Index < Override->Size; Index++) {
+    if (((Override->Table[Index].OverrideConfig & PchPcieL1SubstatesOverride) == PchPcieL1SubstatesOverride) &&
+        (Override->Table[Index].VendorId == VendorId) &&
+        (Override->Table[Index].DeviceId == DeviceId) &&
+        (Override->Table[Index].RevId == Revision || Override->Table[Index].RevId == 0xFFFF)) {
+      return Override->Table[Index].L1SubstatesCapOffset;
+    }
+  }
+  return 0;
+}
+
+/**
+  There are some devices whose implementation of L1 substates is partially broken. This function checks
+  list of such devices and if one is found, overrides their L1ss-related capabilities
+
+  @param[in]     Base       base address of device
+  @param[in]     Override   table of devices that need override
+  @param[in,out] L1ss       on entry, capabilities read from register; on exit, capabilities modified according ot override table
+**/
+STATIC
+VOID
+OverrideL1ssCaps (
+  UINT64         Base,
+  OVERRIDE_TABLE *Override,
+  L1SS_CAPS      *L1ss
+  )
+{
+  UINT16 DeviceId;
+  UINT16 VendorId;
+  UINT8  Revision;
+  UINT32 Index;
+
+  VendorId = PciSegmentRead16 (Base + PCI_VENDOR_ID_OFFSET);
+  DeviceId = PciSegmentRead16 (Base + PCI_DEVICE_ID_OFFSET);
+  Revision = PciSegmentRead8  (Base + PCI_REVISION_ID_OFFSET);
+
+  for (Index = 0; Index < Override->Size; Index++) {
+    if (((Override->Table[Index].OverrideConfig & PchPcieL1SubstatesOverride) == PchPcieL1SubstatesOverride) &&
+        (Override->Table[Index].VendorId == VendorId) &&
+        (Override->Table[Index].DeviceId == DeviceId) &&
+        (Override->Table[Index].RevId == Revision || Override->Table[Index].RevId == 0xFF)) {
+
+      L1ss->PmL12   &= !!(Override->Table[Index].L1SubstatesCapMask & B_PCIE_EX_L1SCAP_PPL12S);
+      L1ss->PmL11   &= !!(Override->Table[Index].L1SubstatesCapMask & B_PCIE_EX_L1SCAP_PPL11S);
+      L1ss->AspmL12 &= !!(Override->Table[Index].L1SubstatesCapMask & B_PCIE_EX_L1SCAP_AL12S);
+      L1ss->AspmL11 &= !!(Override->Table[Index].L1SubstatesCapMask & B_PCIE_EX_L1SCAP_AL1SS);
+      if (Override->Table[Index].L1sTpowerOnValue != 0) {
+        L1ss->Cmrt = Override->Table[Index].L1sCommonModeRestoreTime;
+        L1ss->TpoScale = Override->Table[Index].L1sTpowerOnScale;
+        L1ss->TpoValue = Override->Table[Index].L1sTpowerOnValue;
+      }
+      return;
+    }
+  }
+}
+
+/**
+  Returns L1 sub states capabilities of a device
+
+  @param[in] Base   base address of a device
+
+  @retval L1SS_CAPS structure filled with device's capabilities
+**/
+STATIC
+L1SS_CAPS
+GetL1ssCaps (
+  UINT64         Base,
+  OVERRIDE_TABLE *Override
+  )
+{
+  L1SS_CAPS Capabilities = {0};
+  UINT16    PcieCapOffset;
+  UINT32    CapsRegister;
+
+  PcieCapOffset = GetOverrideL1ssCapsOffset (Base, Override);
+  if (PcieCapOffset == 0) {
+    PcieCapOffset = PcieBaseFindExtendedCapId (Base, V_PCIE_EX_L1S_CID);
+  }
+  if (PcieCapOffset == 0) {
+    return Capabilities;
+  }
+  CapsRegister = PciSegmentRead32 (Base + PcieCapOffset + R_PCIE_EX_L1SCAP_OFFSET);
+  if (CapsRegister & B_PCIE_EX_L1SCAP_L1PSS) {
+    //
+    // Skip L1.1 checking since some device only indecate L1.2 support.
+    // [1604452805]
+    //
+    Capabilities.PmL11 = !!(CapsRegister & B_PCIE_EX_L1SCAP_PPL11S);
+    Capabilities.PmL12 = !!(CapsRegister & B_PCIE_EX_L1SCAP_PPL12S);
+    Capabilities.AspmL12 = !!(CapsRegister & B_PCIE_EX_L1SCAP_AL12S);
+    Capabilities.AspmL11 = !!(CapsRegister & B_PCIE_EX_L1SCAP_AL1SS);
+    Capabilities.Cmrt = (CapsRegister & B_PCIE_EX_L1SCAP_CMRT) >> N_PCIE_EX_L1SCAP_CMRT;
+    Capabilities.TpoValue = (CapsRegister & B_PCIE_EX_L1SCAP_PTV) >> N_PCIE_EX_L1SCAP_PTV;
+    Capabilities.TpoScale = (CapsRegister & B_PCIE_EX_L1SCAP_PTPOS) >> N_PCIE_EX_L1SCAP_PTPOS;
+  }
+  OverrideL1ssCaps (Base, Override, &Capabilities);
+  return Capabilities;
+}
+
+/**
+  Returns combination of two sets of L1 substate capabilities
+  Given feature is supported by the link only if both sides support it
+  Time parameters for link (Cmrt and Tpo) depend on the bigger value between two sides
+
+  @param[in] L1ssA      L1 substate capabilities of first device
+  @param[in] L1ssB      L1 substate capabilities of second device
+
+  @retval Link's L1 substate capabilities
+**/
+STATIC
+L1SS_CAPS
+CombineL1ss (
+  L1SS_CAPS L1ssA,
+  L1SS_CAPS L1ssB
+  )
+{
+  L1SS_CAPS Combined;
+
+  Combined.PmL12 = L1ssA.PmL12 && L1ssB.PmL12;
+  Combined.PmL11 = L1ssA.PmL11 && L1ssB.PmL11;
+  Combined.AspmL12 = L1ssA.AspmL12 && L1ssB.AspmL12;
+  Combined.AspmL11 = L1ssA.AspmL11 && L1ssB.AspmL11;
+  Combined.Cmrt = MAX (L1ssA.Cmrt, L1ssB.Cmrt);
+  if (TpoToUs (L1ssA.TpoScale, L1ssA.TpoValue) > TpoToUs (L1ssB.TpoScale, L1ssB.TpoValue)) {
+    Combined.TpoScale = L1ssA.TpoScale;
+    Combined.TpoValue = L1ssA.TpoValue;
+  } else {
+    Combined.TpoScale = L1ssB.TpoScale;
+    Combined.TpoValue = L1ssB.TpoValue;
+  }
+  return Combined;
+}
+
+/**
+  Configures L1 substate feature in a device
+
+  @param[in] Sbdf     segment:bus:device:function coordinates of a device
+  @param[in] L1ss     configuration to be programmed
+  @param[in] Override table of devices that require special handling
+**/
+STATIC
+VOID
+SetL1ss (
+  SBDF           Sbdf,
+  L1SS_CAPS      L1ss,
+  OVERRIDE_TABLE *Override,
+  BOOLEAN   IsCpuPcie
+
+  )
+{
+  UINT16    PcieCapOffset;
+  UINT32    Ctrl1Register;
+  UINT32    Ctrl2Register;
+  UINT64    Base;
+
+  Base = SbdfToBase(Sbdf);
+  Ctrl1Register = 0;
+  Ctrl2Register = 0;
+
+  PcieCapOffset = GetOverrideL1ssCapsOffset (Base, Override);
+  if (PcieCapOffset == 0) {
+    PcieCapOffset = PcieBaseFindExtendedCapId (Base, V_PCIE_EX_L1S_CID);
+  }
+  if (PcieCapOffset == 0) {
+    return;
+  }
+
+  Ctrl1Register |= (L1ss.PmL12 ? B_PCIE_EX_L1SCAP_PPL12S : 0);
+  Ctrl1Register |= (L1ss.PmL11 ? B_PCIE_EX_L1SCAP_PPL11S : 0);
+  Ctrl1Register |= (L1ss.AspmL12 ? B_PCIE_EX_L1SCAP_AL12S : 0);
+  Ctrl1Register |= (L1ss.AspmL11 ? B_PCIE_EX_L1SCAP_AL1SS : 0);
+  if ((GetDeviceType (Sbdf) == DevTypePcieDownstream)) {
+    Ctrl1Register |= (L1ss.Cmrt << N_PCIE_EX_L1SCAP_CMRT);
+  }
+  ///
+  /// BWG 1.3 Section 5.5.7.6 LTR Threshold Latency
+  /// Set L1.2 LTR threshold using formula (TpoToUs (L1ss.TpoScale, L1ss.TpoValue) + L1ss.Cmrt + 10)
+  ///
+  Ctrl1Register |= ((TpoToUs (L1ss.TpoScale, L1ss.TpoValue) + L1ss.Cmrt + 10) << N_PCIE_EX_L1SCTL1_L12LTRTLV);
+  Ctrl1Register |= (2 << N_PCIE_EX_L1SCTL1_L12LTRTLSV);
+
+  Ctrl2Register |= (L1ss.TpoScale);
+  Ctrl2Register |= (L1ss.TpoValue << N_PCIE_EX_L1SCTL2_POWT);
+  //
+  // Set CLKREQ Acceleration Interrupt Enable
+  //
+  Ctrl1Register |= B_PCIE_EX_L1SCTL1_L1SSEIE;
+  PciSegmentWrite32 (Base + PcieCapOffset + R_PCIE_EX_L1SCTL1_OFFSET, 0);
+  PciSegmentWrite32 (Base + PcieCapOffset + R_PCIE_EX_L1SCTL2_OFFSET, Ctrl2Register);
+  PciSegmentWrite32 (Base + PcieCapOffset + R_PCIE_EX_L1SCTL1_OFFSET, Ctrl1Register);
+}
+
+/**
+  Converts L1 latency from enumerated register value to microseconds
+
+  @param[in] L1Latency     latency value retrieved from register; see PCIE specification for encoding
+
+  @retval    L1 latency converted to microseconds
+**/
+UINT32
+L1LatencyToUs (
+  UINT32 L1Latency
+  )
+{
+  if (L1Latency < 7) {
+    return 1 * (BIT0 << L1Latency);
+  } else {
+    return ASPM_L1_NO_LIMIT;
+  }
+}
+
+/**
+  Modifies L1 latency by provided value
+
+  @param[in] Aspm     Structure that contains ASPM capabilities of a link, including L1 acceptable latency
+  @param[in] Value    Value, in microseconds, to be added to L1 acceptable latency. Can be negative.
+
+  @retval             Aspm structure with modified L1 acceptable latency
+**/
+STATIC
+ASPM_CAPS
+PatchL1AcceptableLatency (
+  ASPM_CAPS Aspm,
+  INT8      Value
+  )
+{
+  if (Aspm.L1AcceptableLatencyUs != ASPM_L1_NO_LIMIT) {
+    if (Value > 0) {
+      Aspm.L1AcceptableLatencyUs += Value;
+    } else {
+      if (Aspm.L1AcceptableLatencyUs > (UINT32)(-1*Value)) {
+        Aspm.L1AcceptableLatencyUs = Aspm.L1AcceptableLatencyUs + Value;
+      } else {
+        Aspm.L1AcceptableLatencyUs = 0;
+      }
+    }
+  }
+  return Aspm;
+}
+
+/**
+  Reads ASPM capabilities of a device
+
+  @param[in] Sbdf segment:bus:device:function coordinates of a device
+
+  @retval           structure containing device's ASPM capabilities
+**/
+STATIC
+ASPM_CAPS
+GetAspmCaps (
+  SBDF   Sbdf
+  )
+{
+
+  UINT32    LinkCapRegister;
+  UINT32    DevCapRegister;
+  UINT64    Base;
+  ASPM_CAPS Aspm = {0};
+
+  Base = SbdfToBase (Sbdf);
+
+  LinkCapRegister = PciSegmentRead32 (Base + Sbdf.PcieCap + R_PCIE_LCAP_OFFSET);
+  DevCapRegister = PciSegmentRead32 (Base + Sbdf.PcieCap + R_PCIE_DCAP_OFFSET);
+
+  ///
+  /// Check endpoint for pre-1.1 devices based on the Role based Error Reporting Capability bit. Don't report L0s support for old devices
+  ///
+  if (DevCapRegister & B_PCIE_DCAP_RBER) {
+    Aspm.L0sSupported = !!(LinkCapRegister & B_PCIE_LCAP_APMS_L0S);
+  }
+  Aspm.L1Supported = !!(LinkCapRegister & B_PCIE_LCAP_APMS_L1);
+
+  Aspm.LinkL0sExitLatency = (LinkCapRegister & B_PCIE_LCAP_EL0) >> N_PCIE_LCAP_EL0;
+  Aspm.LinkL1ExitLatencyUs = L1LatencyToUs( (LinkCapRegister & B_PCIE_LCAP_EL1) >> N_PCIE_LCAP_EL1);
+
+  if (GetDeviceType (Sbdf) == DevTypePcieEndpoint) {
+    Aspm.L0sAcceptableLatency = (DevCapRegister & B_PCIE_DCAP_E0AL) >> N_PCIE_DCAP_E0AL;
+    Aspm.L1AcceptableLatencyUs = L1LatencyToUs( (DevCapRegister & B_PCIE_DCAP_E1AL) >> N_PCIE_DCAP_E1AL);
+    DEBUG ((DEBUG_INFO, "GetAspmCaps %02x:%02x:%02x L0s%c %d:%d L1%c %d:%d\n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func,
+                                                                           Aspm.L0sSupported?'+':'-', Aspm.LinkL0sExitLatency, Aspm.L0sAcceptableLatency,
+                                                                           Aspm.L1Supported?'+':'-', Aspm.LinkL1ExitLatencyUs, Aspm.L1AcceptableLatencyUs));
+  } else {
+    Aspm.L0sAcceptableLatency = ASPM_L0s_NO_LIMIT;
+    Aspm.L1AcceptableLatencyUs = ASPM_L1_NO_LIMIT;
+    DEBUG ((DEBUG_INFO, "GetAspmCaps %02x:%02x:%02x L0s%c %d:x L1%c %d:x\n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func,
+                                                                           Aspm.L0sSupported?'+':'-', Aspm.LinkL0sExitLatency,
+                                                                           Aspm.L1Supported?'+':'-', Aspm.LinkL1ExitLatencyUs));
+  }
+  return Aspm;
+}
+
+/**
+  Get ASPM L0s and L1 override of given device.
+
+  @param[in] Sbdf                Segment,Bus,Device,Function address of currently visited PCIe device
+  @param[in,out] MyAspm          Current device's ASPM capabilities structure
+  @param[in] Override            Pch Pcie devices OverrideTable
+**/
+STATIC
+VOID
+GetOverrideAspm (
+  SBDF           Sbdf,
+  ASPM_CAPS      *MyAspm,
+  OVERRIDE_TABLE *Override
+  )
+{
+  UINT16      DeviceId;
+  UINT16      VendorId;
+  UINT8       Revision;
+  UINT32      Index;
+  UINT64      Base;
+
+  Base = SbdfToBase (Sbdf);
+
+  VendorId = PciSegmentRead16 (Base + PCI_VENDOR_ID_OFFSET);
+  DeviceId = PciSegmentRead16 (Base + PCI_DEVICE_ID_OFFSET);
+  Revision = PciSegmentRead8  (Base + PCI_REVISION_ID_OFFSET);
+
+  for (Index = 0; Index < Override->Size; Index++) {
+    if (((Override->Table[Index].OverrideConfig & PchPcieL1L2Override) == PchPcieL1L2Override) &&
+        (Override->Table[Index].VendorId == VendorId) &&
+        (Override->Table[Index].DeviceId == DeviceId) &&
+        (Override->Table[Index].RevId == Revision || Override->Table[Index].RevId == 0xFF)) {
+      DEBUG ((DEBUG_INFO, "GetOverrideAspm %02x:%02x:%02x, original L0sSupported = 0x%x, L1Supported = 0x%x\n",
+              Sbdf.Bus, Sbdf.Dev, Sbdf.Func, MyAspm->L0sSupported, MyAspm->L1Supported));
+      if (MyAspm->L0sSupported) {
+        //
+        // If L0s is supported in capability, apply platform override.
+        //
+        MyAspm->L0sSupported = Override->Table[Index].EndPointAspm & BIT0;
+      }
+      if (MyAspm->L1Supported) {
+        //
+        // If L1 is supported in capability, apply platform override.
+        //
+        MyAspm->L1Supported = (Override->Table[Index].EndPointAspm & BIT1) >> 1;
+      }
+      DEBUG ((DEBUG_INFO, "GetOverrideAspm %02x:%02x:%02x, override L0sSupported = 0x%x, L1Supported = 0x%x\n",
+              Sbdf.Bus, Sbdf.Dev, Sbdf.Func, MyAspm->L0sSupported, MyAspm->L1Supported));
+    }
+  }
+}
+
+/**
+  Combines ASPM capabilities of two devices on both ends of a link to determine link's ASPM capabilities
+
+  @param[in] AspmA, AspmB  ASPM capabilities of two devices
+
+  @retval    ASPM_CAPS structure containing combined ASPM capabilities
+**/
+STATIC
+ASPM_CAPS
+CombineAspm (
+  ASPM_CAPS AspmA,
+  ASPM_CAPS AspmB,
+  BOOLEAN   DownstreamPort
+  )
+{
+  ASPM_CAPS Combined;
+
+  if (DownstreamPort) {
+    //
+    // When combining ASPM in downstream ports, combination must reflect state of link just below
+    // and consider all acceptable latencies of all endpoints anywhere down below that port
+    //
+    Combined.L0sSupported = AspmA.L0sSupported & AspmB.L0sSupported;
+    Combined.L1Supported = AspmA.L1Supported & AspmB.L1Supported;
+    Combined.LinkL0sExitLatency = MAX (AspmA.LinkL0sExitLatency, AspmB.LinkL0sExitLatency);
+    Combined.LinkL1ExitLatencyUs = MAX (AspmA.LinkL1ExitLatencyUs, AspmB.LinkL1ExitLatencyUs);
+    Combined.L0sAcceptableLatency = MIN (AspmA.L0sAcceptableLatency, AspmB.L0sAcceptableLatency);
+    Combined.L1AcceptableLatencyUs = MIN (AspmA.L1AcceptableLatencyUs, AspmB.L1AcceptableLatencyUs);
+  } else {
+    //
+    // When combining ASPM in switch upstream ports,
+    // Supported and ExitLatency must only reflect capabilities of upstream port itself
+    // But acceptable latencies must consider all endpoints anywhere below
+    //
+    Combined.L0sSupported = AspmA.L0sSupported;
+    Combined.L1Supported = AspmA.L1Supported;
+    Combined.LinkL0sExitLatency = AspmA.LinkL0sExitLatency;
+    Combined.LinkL1ExitLatencyUs = AspmA.LinkL1ExitLatencyUs;
+    Combined.L0sAcceptableLatency = MIN (AspmA.L0sAcceptableLatency, AspmB.L0sAcceptableLatency);
+    Combined.L1AcceptableLatencyUs = MIN (AspmA.L1AcceptableLatencyUs, AspmB.L1AcceptableLatencyUs);
+  }
+  DEBUG ((DEBUG_INFO, "CombineAspm %x:%x -> %x\n", AspmA.L1AcceptableLatencyUs, AspmB.L1AcceptableLatencyUs, Combined.L1AcceptableLatencyUs));
+  return Combined;
+}
+
+/**
+  Checks if L1 can be enabled on given link, according to ASPM parameters of that link
+
+  @param[in] Aspm            set of parameters describing this link and endpoint devices below it
+
+  @retval    TRUE if L1 can be enabled
+**/
+STATIC
+BOOLEAN
+IsL1Allowed (
+  ASPM_CAPS Aspm
+  )
+{
+  return (Aspm.L1Supported && (Aspm.L1AcceptableLatencyUs >= Aspm.LinkL1ExitLatencyUs));
+}
+
+/**
+  Checks if L0s can be enabled on given link, according to ASPM parameters of that link
+
+  @param[in] Aspm            set of parameters describing this link and endpoint devices below it
+
+  @retval    TRUE if L0s can be enabled
+**/
+STATIC
+BOOLEAN
+IsL0sAllowed (
+  ASPM_CAPS Aspm
+  )
+{
+  return (Aspm.L0sSupported && (Aspm.L0sAcceptableLatency >= Aspm.LinkL0sExitLatency));
+}
+
+/**
+  Enables L0s and L1 for given port, if possible.
+  L0s/L1 can be enabled if it's supported on both sides of a link and if link's latency doesn't exceed
+  acceptable latency of any endpoint below this link
+
+  @param[in] Base            device's base address
+  @param[in] Aspm            set of parameters describing this link and endpoint devices below it
+**/
+STATIC
+VOID
+SetAspm (
+  SBDF      Sbdf,
+  ASPM_CAPS Aspm
+  )
+{
+  UINT16 DataOr;
+
+  DataOr = 0;
+  if (IsL0sAllowed (Aspm)) {
+    DataOr |= V_PCIE_LCTL_ASPM_L0S;
+  }
+  if (IsL1Allowed (Aspm)) {
+    DataOr |= V_PCIE_LCTL_ASPM_L1;
+  }
+  DEBUG ((DEBUG_INFO, "SetAspm on %02x:%02x:%02x to %d\n", Sbdf.Bus,Sbdf.Dev,Sbdf.Func, DataOr));
+  PciSegmentAndThenOr16 (SbdfToBase (Sbdf) + Sbdf.PcieCap + R_PCIE_LCTL_OFFSET, (UINT16)~B_PCIE_LCTL_ASPM, DataOr);
+}
+
+/**
+  Adds device entry to a list of devices.
+
+  @param[in,out] Table    array of devices
+  @param[in]     Sbdf     segment:bus:device:function coordinates of device to be added to table
+**/
+STATIC
+VOID
+AddToDeviceTable (
+  SBDF_TABLE *Table,
+  SBDF       Sbdf
+  )
+{
+  if (Table->Count < MAX_SBDF_TABLE_SIZE) {
+    Table->Entry[Table->Count++] = Sbdf;
+  } else {
+    ASSERT (FALSE);
+  }
+}
+
+/**
+  Remove device entry from a list and clear its bus assignment
+
+  @param[in,out] Table    array of devices
+**/
+STATIC
+VOID
+ClearBusFromTable (
+  SBDF_TABLE *Table
+  )
+{
+  while (Table->Count > 0) {
+    PciSegmentWrite32 (SbdfToBase (Table->Entry[Table->Count - 1]) + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, 0);
+    Table->Count--;
+  }
+}
+
+/**
+  Attempts to assign secondary and subordinate bus numbers to uninitialized bridges in PCIe tree
+  If the device is a bridge and already has bus numbers assigned, they won't be changed
+  Otherwise new bus number will be assigned below this bridge.
+  This function can be called from SMM, where BIOS must not modify bus numbers to prevent
+  conflict with OS enumerator. To prevent this, this function returns list of bridges whose
+  bus numbers were changed. All devices from that list must have buses cleared afterwards.
+
+  @param[in] Sbdf                segment:bus:device:function coordinates of device to be added to table
+  @param[in] MinBus              minimum Bus number that can be assigned below this port
+  @param[in] MaxBus              maximum Bus number that can be assigned below this port
+  @param[in] BridgeCleanupList   list of bridges where bus numbers were modified
+
+  @retval    maximum bus number assigned anywhere below this device
+**/
+STATIC
+UINT8
+RecursiveBusAssignment (
+  SBDF       Sbdf,
+  UINT8      MinBus,
+  UINT8      MaxBus,
+  SBDF_TABLE *BridgeCleanupList
+  )
+{
+  UINT64  Base;
+  SBDF    ChildSbdf;
+  PCI_DEV_TYPE DevType;
+  UINT32  Data32;
+  UINT8   BelowBus;
+  UINT8   SecondaryBus;
+  UINT8   SubordinateBus;
+
+  ChildSbdf.Seg = Sbdf.Seg;
+  InitChildFinder (&ChildSbdf);
+  Base = SbdfToBase (Sbdf);
+
+  //
+  // On way down:
+  //   assign secondary bus, then increase it by one before stepping down; temporarily assign max subordinate bus
+  // On way up:
+  //   fix subordinate bus assignment to equal max bus number assigned anywhere below; return that number
+  //
+  DevType = GetDeviceType (Sbdf);
+  if ((Sbdf.Bus >= MaxBus) || (DevType == DevTypePcieEndpoint) || (DevType == DevTypePci)) {
+    return (UINT8) Sbdf.Bus;
+  } else  {
+    Data32 = PciSegmentRead32 (Base + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET);
+    SecondaryBus = (UINT8)((Data32 & B_PCI_BRIDGE_BNUM_SCBN) >> 8);
+    SubordinateBus = (UINT8)((Data32 & B_PCI_BRIDGE_BNUM_SBBN) >> 16);
+    if (SecondaryBus != 0) {
+      ChildSbdf.Bus = SecondaryBus;
+      MinBus = SecondaryBus + 1;
+      DEBUG ((DEBUG_INFO, "RecursiveBusAssignmentP %x:%x:%x -> %x,%x,%x \n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func, Sbdf.Bus, MinBus, SubordinateBus));
+      while (FindNextPcieChild (DevType, &ChildSbdf)) {
+        BelowBus = RecursiveBusAssignment (ChildSbdf, MinBus, SubordinateBus, BridgeCleanupList);
+        MinBus = BelowBus + 1;
+      }
+      return SubordinateBus;
+    } else {
+      Data32 = Sbdf.Bus + (MinBus << 8) + (MaxBus << 16);
+      PciSegmentWrite32(Base + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, Data32);
+      AddToDeviceTable (BridgeCleanupList, Sbdf);
+      DEBUG ((DEBUG_INFO, "RecursiveBusAssignmentE %x:%x:%x -> %x,%x,%x \n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func, Sbdf.Bus, MinBus, MaxBus));
+      BelowBus = MinBus;
+      ChildSbdf.Bus = MinBus;
+      MinBus++;
+      while (FindNextPcieChild (DevType, &ChildSbdf)) {
+        BelowBus = RecursiveBusAssignment (ChildSbdf, MinBus, MaxBus, BridgeCleanupList);
+        MinBus = BelowBus + 1;
+      }
+      Data32  &= ~B_PCI_BRIDGE_BNUM_SBBN;
+      Data32 |= (BelowBus << 16);
+      PciSegmentWrite32 (Base + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, Data32);
+      DEBUG ((DEBUG_INFO, "RecursiveBusAssignmentL %x:%x:%x -> %x,%x,%x \n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func, Sbdf.Bus, (Data32&0xFF00)>>8, BelowBus));
+      return BelowBus;
+    }
+  }
+}
+
+/**
+  Enables L0s and/or L1 for PCIE links in the hierarchy below
+  L0s/L1 can be enabled when both sides of a link support it and link latency is smaller than acceptable latency
+  ASPM of a given link is independend from any other link (except 1ms L1 adjustment, read below), so it's possible to
+  have a hierarchy when RP link has no ASPM but links below do.
+
+  @param[in] Segment,Bus,Device,Function    address of currently visited PCIe device
+  @param[in] Depth                          How many links there are between this port and root complex
+  @param[in] Override                       Pch Pcie devices OverrideTable
+
+  @retval structure that describes acceptable latencies of all endpoints below plus ASPM parameters of last link
+**/
+STATIC
+ASPM_CAPS
+RecursiveAspmConfiguration (
+  SBDF           Sbdf,
+  UINT8          Depth,
+  OVERRIDE_TABLE *Override
+  )
+{
+  SBDF         ChildSbdf;
+  ASPM_CAPS    MyAspm;
+  ASPM_CAPS    ChildAspm;
+  PCI_DEV_TYPE DevType;
+
+  DEBUG ((DEBUG_INFO, "RecursiveAspmConfiguration %x:%x:%x\n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func));
+
+  //
+  // On way down:
+  //   pass number of links traversed; increase it per upstream port visited (not endpoint)
+  // On way up:
+  //   EndPoint: read Acceptable Latencies; subtract Depth From L1AcceptableLat to account for "1us per switch additional delay"
+  //   Downstreamport: AND L0s/L1 caps; calculate LinkLatency; enable L0s/L1 if supported and if acceptable latency is bigger than link latency;
+  //     if L1 not enabled, add back 1us to Acceptable Latency to cancel earlier Depth subtraction
+  //   UpstreamPort: calculate minimum of below Acceptable Latencies; return that, with upper link's Latency and L0s/L1 support
+  //
+  DevType = GetDeviceType(Sbdf);
+  if (DevType == DevTypePcieUpstream) {
+    Depth++;
+  }
+  MyAspm = GetAspmCaps (Sbdf);
+  //
+  // Get ASPM L0s and L1 override
+  //
+  if (Override != NULL) {
+    GetOverrideAspm (Sbdf, &MyAspm, Override);
+  }
+  if (DevType == DevTypePcieEndpoint) {
+    //
+    // Every switch between endpoint and CPU introduces 1us additional latency on L1 exit. This is reflected by
+    // subtracting 1us per switch from endpoint's acceptable L1 latency.
+    // In case L1 doesn't get enabled in one of switches, that 1us will be added back.
+    // This calculation is not precise. It ignores that some switches' added delay may be shadowed by
+    // other links' exit latency. But it guarantees that acceptable latency won't be exceeded and is simple
+    // enough to perform in a single iteration without backtracking.
+    //
+    return PatchL1AcceptableLatency (MyAspm, (-1 * Depth));
+  }
+  if (HasChildBus (Sbdf, &ChildSbdf)) {
+    while (FindNextPcieChild (DevType, &ChildSbdf)) {
+      ChildAspm = RecursiveAspmConfiguration (ChildSbdf, Depth, Override);
+      MyAspm = CombineAspm (MyAspm, ChildAspm, (DevType == DevTypePcieDownstream));
+    }
+    if (DevType == DevTypePcieDownstream) {
+      SetAspm (Sbdf, MyAspm);
+      //
+      // ASPM config must be consistent across all functions of a device. That's why there's while loop.
+      //
+      while (FindNextPcieChild (DevType, &ChildSbdf)) {
+        SetAspm (ChildSbdf, MyAspm);
+      }
+      if (!IsL1Allowed (MyAspm)) {
+        MyAspm = PatchL1AcceptableLatency (MyAspm, 1);
+      }
+    }
+  }
+  return MyAspm;
+}
+
+/**
+  Enables L1 substates for PCIE links in the hierarchy below
+  L1.1 / L1.2 can be enabled if both sides of a link support it.
+
+  @param[in] Segment,Bus,Device,Function    address of currently visited PCIe device
+
+  @retval  structure that describes L1ss capabilities of the device
+**/
+STATIC
+L1SS_CAPS
+RecursiveL1ssConfiguration (
+  SBDF           Sbdf,
+  OVERRIDE_TABLE *Override
+  )
+{
+  UINT64  Base;
+  SBDF    ChildSbdf;
+  L1SS_CAPS CombinedCaps;
+  L1SS_CAPS ChildCaps;
+  PCI_DEV_TYPE DevType;
+  BOOLEAN   IsCpuPcie;
+  UINT32    DevNum;
+
+  IsCpuPcie = FALSE;
+
+  DEBUG ((DEBUG_INFO, "RecursiveL1ssConfiguration %x:%x:%x\n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func));
+
+  Base = SbdfToBase (Sbdf);
+  DevNum = Sbdf.Dev;
+  if (DevNum == SA_PEG0_DEV_NUM || DevNum == SA_PEG3_DEV_NUM) {
+    IsCpuPcie = TRUE;
+  }
+  //
+  // On way down:
+  //   do nothing
+  // On way up:
+  //   In downstream ports, combine L1ss capabilities of that port and device behind it, then enable L1.1 and/or L1.2 if possible
+  //   Return L1ss capabilities
+  //
+  if (HasChildBus (Sbdf, &ChildSbdf)) {
+    DevType = GetDeviceType (Sbdf);
+    while (FindNextPcieChild (DevType, &ChildSbdf)) {
+      ChildCaps = RecursiveL1ssConfiguration (ChildSbdf, Override);
+      if (DevType == DevTypePcieDownstream && ChildSbdf.Func == 0) {
+        CombinedCaps = CombineL1ss (GetL1ssCaps (Base, Override), ChildCaps);
+        SetL1ss (Sbdf, CombinedCaps, Override, IsCpuPcie);
+        SetL1ss (ChildSbdf, CombinedCaps, Override, IsCpuPcie);
+      }
+    }
+  }
+  return GetL1ssCaps (Base, Override);
+}
+
+/**
+  Checks if there is an IoAPIC device in the PCIe hierarchy.
+  If one is found, this function doesn't check for more and returns
+
+  @param[in] BusLimit                       maximum Bus number that can be assigned below this port
+  @param[in] Segment,Bus,Device,Function    address of currently visited PCIe device
+
+  @retval  TRUE if IoAPIC device was found
+**/
+STATIC
+BOOLEAN
+RecursiveIoApicCheck (
+  SBDF       Sbdf
+  )
+{
+  SBDF         ChildSbdf;
+  UINT8        IoApicPresent;
+  PCI_DEV_TYPE DevType;
+
+  DEBUG ((DEBUG_INFO, "RecursiveIoApicCheck %x:%x:%x\n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func));
+
+  IoApicPresent = FALSE;
+
+  if (IsIoApicDevice (SbdfToBase (Sbdf))) {
+    DEBUG ((DEBUG_INFO, "IoApicFound @%x:%x:%x:%x\n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func));
+    return TRUE;
+  }
+  if (HasChildBus (Sbdf, &ChildSbdf)) {
+    DevType = GetDeviceType (Sbdf);
+    while (FindNextPcieChild (DevType, &ChildSbdf)) {
+      IoApicPresent = RecursiveIoApicCheck (ChildSbdf);
+      if (IoApicPresent) {
+        break;
+      }
+    }
+  }
+  DEBUG ((DEBUG_INFO, "IoApic status %d @%x:%x:%x:%x\n", IoApicPresent, Sbdf.Seg, Sbdf.Bus, Sbdf.Dev, Sbdf.Func));
+  return IoApicPresent;
+}
+
+/**
+  Calculates Maximum Payload Size supported by PCIe hierarchy.
+  Starting from a device, it finds the minimum MPS supported by devices below it.
+  There are many valid strategies for setting MPS. This implementation chooses
+  one that is safest, but doesn't guarantee maximum performance:
+    Find minimum MPS under given rootport, then program that minimum value everywhere below that rootport
+
+  @param[in] BusLimit                       maximum Bus number that can be assigned below this port
+  @param[in] Segment,Bus,Device,Function    address of currently visited PCIe device
+
+  @retval  MPS supported by PCIe hierarchy, calculated as MIN(MPS of all devices below)
+**/
+STATIC
+UINT8
+RecursiveMpsCheck (
+  SBDF       Sbdf
+  )
+{
+  SBDF         ChildSbdf;
+  UINT8        MyMps;
+  UINT8        SubtreeMps;
+  PCI_DEV_TYPE DevType;
+
+  DEBUG ((DEBUG_INFO, "RecursiveMpsCheck %x:%x:%x\n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func));
+
+  MyMps = GetMps (Sbdf);
+  if (MyMps == 0) {
+    return MyMps;
+  }
+  if (HasChildBus (Sbdf, &ChildSbdf)) {
+    DevType = GetDeviceType (Sbdf);
+    while (FindNextPcieChild (DevType, &ChildSbdf)) {
+      SubtreeMps = RecursiveMpsCheck (ChildSbdf);
+      MyMps = MIN(MyMps, SubtreeMps);
+    }
+  }
+  return MyMps;
+}
+
+/**
+  Sets Maximum Payload Size in PCIe hierarchy.
+  Starting from a device, it programs the same MPS value to it and all devices below it.
+  There are many valid strategies for setting MPS. This implementation chooses
+  one that is safest, but doesn't guarantee maximum performance:
+    Find minimum MPS under given rootport, then program that minimum value everywhere below that rootport
+
+  @param[in] BusLimit                       maximum Bus number that can be assigned below this port
+  @param[in] Segment,Bus,Device,Function    address of currently visited PCIe device
+  @param[in] Mps                            Maximum Payload Size to be programmed
+**/
+STATIC
+VOID
+RecursiveMpsConfiguration (
+  SBDF       Sbdf,
+  UINT8      Mps
+  )
+{
+  SBDF    ChildSbdf;
+  PCI_DEV_TYPE DevType;
+
+  DEBUG ((DEBUG_INFO, "RecursiveMpsConfiguration %x:%x:%x\n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func));
+
+  if (HasChildBus (Sbdf, &ChildSbdf)) {
+    DevType = GetDeviceType (Sbdf);
+    while (FindNextPcieChild (DevType, &ChildSbdf)) {
+      RecursiveMpsConfiguration (ChildSbdf, Mps);
+    }
+  }
+  SetMps (Sbdf, Mps);
+}
+
+/**
+  Sets Enable Clock Power Management bit for devices that support it.
+  A device supports CPM only if all function of this device report CPM support.
+  Downstream ports never report CPM capability, so it's only relevant for upstream ports.
+  When this function executes on upstream component, it will check CPM & set ECPM of downstream component
+  When this function executes on downstream component, all devices below it are guaranteed to
+  return CPM=0 so it will do nothing
+
+  @param[in] Segment,Bus,Device,Function    address of currently visited PCIe device
+
+  @retval TRUE = this device supports CPM, FALSE = it doesn't
+**/
+STATIC
+BOOLEAN
+RecursiveCpmConfiguration (
+  SBDF       Sbdf
+  )
+{
+  SBDF         ChildSbdf;
+  BOOLEAN      ChildCpm;
+  PCI_DEV_TYPE DevType;
+
+  DEBUG ((DEBUG_INFO, "RecursiveCpmConfiguration %x:%x:%x\n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func));
+
+  ChildCpm = FALSE;
+
+  if (HasChildBus (Sbdf, &ChildSbdf)) {
+    ChildCpm = TRUE;
+    DevType = GetDeviceType (Sbdf);
+    while (FindNextPcieChild (DevType, &ChildSbdf)) {
+      ChildCpm &= RecursiveCpmConfiguration (ChildSbdf);
+    }
+    if (ChildCpm) {
+      while (FindNextPcieChild (DevType, &ChildSbdf)) {
+        EnableCpm (ChildSbdf);
+      }
+    }
+  }
+  return IsCpmSupported (Sbdf);
+}
+
+/**
+  Sets Common Clock Configuration bit for devices that share common clock across link
+  Devices on both sides of a PCIE link share common clock if both upstream component
+  and function 0 of downstream component report Slot Clock Configuration bit = 1.
+  When this function executes on upstream component, it checks SCC of both sides of the link
+  If they both support it, sets CCC for both sides (this means all functions of downstream component)
+  When this function executes on downstream component, it only returns SCC capability
+
+  @param[in] Segment,Bus,Device,Function    address of currently visited PCIe device
+  @param[in] WaitForRetrain                 decides if this function should busy-wait for link retrain
+
+  @retval TRUE = this device supports SCC, FALSE = it doesn't
+**/
+STATIC
+BOOLEAN
+RecursiveCccConfiguration (
+  SBDF       Sbdf,
+  BOOLEAN    WaitForRetrain
+  )
+{
+  UINT64       Base;
+  SBDF         ChildSbdf;
+  BOOLEAN      MyScc;
+  BOOLEAN      ChildScc;
+  BOOLEAN      LinkScc;
+  PCI_DEV_TYPE DevType;
+
+  DEBUG ((DEBUG_INFO, "RecursiveCccConfiguration %x:%x:%x\n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func));
+
+  ChildScc = 0;
+  Base = SbdfToBase(Sbdf);
+  MyScc = GetScc (SbdfToBase(Sbdf), (UINT8)Sbdf.PcieCap);
+  if (HasChildBus (Sbdf, &ChildSbdf)) {
+    DevType = GetDeviceType (Sbdf);
+    while (FindNextPcieChild (DevType, &ChildSbdf)) {
+      ChildScc |= RecursiveCccConfiguration (ChildSbdf, WaitForRetrain);
+    }
+    if (DevType == DevTypePcieDownstream) {
+      LinkScc = MyScc & ChildScc;
+      if (LinkScc) {
+        EnableCcc (SbdfToBase(Sbdf), (UINT8)Sbdf.PcieCap);
+        while (FindNextPcieChild (DevType, &ChildSbdf)) {
+          EnableCcc (SbdfToBase(ChildSbdf), (UINT8)ChildSbdf.PcieCap);
+        }
+        RetrainLink(Base, (UINT8)Sbdf.PcieCap, WaitForRetrain);
+      }
+    }
+  }
+  return MyScc;
+}
+
+/**
+  Configures Latency Tolerance Reporting in given device and in PCIe tree below it.
+  This function configures Maximum LTR and enables LTR mechanism. It visits devices using depth-first search
+  and skips branches behind devices which do not support LTR.
+  Maximum LTR:
+    This function will set LTR's upper bound for every visited device. Max LTR value is provided as a parameter
+  Enable LTR:
+    LTR should be enabled top-to-bottom in every visited device that supports LTR. This function does not
+    iterate down behind devices with no LTR support. In effect, LTR will be enabled in given device if that device
+    and all devices above it on the way to RootComplex do support LTR.
+
+  This function expects that bridges have bus numbers already configured
+
+  @param[in] Segment,Bus,Device,Function    address of currently visited PCIe device
+  @param[in] LtrLimit                       Ltr to be programmed to every endpoint
+
+  @retval MaxLTR programmed in this device
+**/
+STATIC
+VOID
+RecursiveLtrConfiguration (
+  SBDF       Sbdf,
+  LTR_LIMIT  LtrLimit
+  )
+{
+  UINT64  Base;
+  SBDF    ChildSbdf;
+  PCI_DEV_TYPE DevType;
+
+  DEBUG ((DEBUG_INFO, "RecursiveLtrConfiguration %x:%x:%x\n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func));
+
+  Base = SbdfToBase(Sbdf);
+
+  if (!IsLtrCapable (Sbdf)) {
+    DEBUG ((DEBUG_INFO, "Not LtrCapable %02x:%02x:%02x\n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func));
+    return;
+  }
+  EnableLtr (Sbdf);
+  if (HasChildBus (Sbdf, &ChildSbdf)) {
+    DevType = GetDeviceType (Sbdf);
+    while (FindNextPcieChild (DevType, &ChildSbdf)) {
+      RecursiveLtrConfiguration (ChildSbdf, LtrLimit);
+    }
+  }
+  SetLtrLimit (Base, LtrLimit);
+}
+
+/**
+  Checks to see device is PTM Capable
+
+  @param[in] Sbdf    device's segment:bus:device:function coordinates
+
+  @retval TRUE = PTM Capability found, FALSE = Not PTM capable
+**/
+STATIC
+BOOLEAN
+IsPtmCapable (
+  SBDF       Sbdf
+  )
+{
+  UINT16     CapHeaderOffset;
+
+  CapHeaderOffset = PcieFindExtendedCapId ((UINT8) Sbdf.Seg, (UINT8) Sbdf.Bus, (UINT8) Sbdf.Dev, (UINT8) Sbdf.Func, V_PCIE_EX_PTM_CID);
+
+  return (CapHeaderOffset != 0);
+}
+
+/**
+  Get PTM Capability register from PCIe Extended Capability Space.
+
+  @param[in] Sbdf                device's segment:bus:device:function coordinates
+  @param[in] PtmCapHeaderOffset  PTM Capability Header Offset
+
+  @retval LocalPtm       Returns PTM Capability.
+                         If Device is not PTM capable then PTM Capability is zeroed out.
+**/
+STATIC
+PTM_CAPS
+GetPtmCapability (
+  SBDF      Sbdf,
+  UINT16    PtmCapHeaderOffset
+  )
+{
+  PTM_CAPS PtmCaps;
+
+  PtmCaps.Uint32 = 0;
+
+  if (PtmCapHeaderOffset != 0) {
+    PtmCaps.Uint32 = PciSegmentRead32 (SbdfToBase (Sbdf) + PtmCapHeaderOffset + R_PCIE_EX_PTMCAP_OFFSET);
+  }
+
+  return PtmCaps;
+}
+
+/**
+  Get PTM Control register from PCIe Extended Capability Space.
+
+  @param[in] Sbdf                device's segment:bus:device:function coordinates
+  @param[in] PtmCapHeaderOffset  PTM Capability Header Offset
+
+  @retval LocalPtm       Returns PTM Control.
+                         If Device is not PTM capable then PTM Control is zeroed out.
+**/
+STATIC
+PTM_CTRL
+GetPtmControl (
+  SBDF      Sbdf,
+  UINT16    PtmCapHeaderOffset
+  )
+{
+  PTM_CTRL PtmCtrl;
+
+  PtmCtrl.Uint32 = 0;
+
+  if (PtmCapHeaderOffset != 0) {
+    PtmCtrl.Uint32 = PciSegmentRead32 (SbdfToBase (Sbdf) + PtmCapHeaderOffset + R_PCIE_EX_PTMCTL_OFFSET);
+  }
+
+  return PtmCtrl;
+}
+
+/**
+  Set PTM Control register in the PCIe Extended Capability Space.
+
+  @param[in] Sbdf                device's segment:bus:device:function coordinates
+  @param[in] PtmCapHeaderOffset  PTM Capability Header Offset
+  @param[in] PtmCtrl             PTM Control Register
+**/
+STATIC
+VOID
+SetPtmControl (
+  SBDF      Sbdf,
+  UINT16    PtmCapHeaderOffset,
+  PTM_CTRL  PtmCtrl
+  )
+{
+  if (PtmCapHeaderOffset != 0) {
+    PciSegmentWrite32 (SbdfToBase (Sbdf) + PtmCapHeaderOffset + R_PCIE_EX_PTMCTL_OFFSET, PtmCtrl.Uint32);
+  }
+}
+
+/**
+  Enable PTM on device's control register. Set the Effective Clock Granularity.
+
+  @param[in]     Sbdf                 device's segment:bus:device:function coordinates
+  @param[in out] EffectiveGranularity Effective Clock Granularity of the PTM hierarchy
+  @param[in out] PtmHierarchy         Indicates if the current device is within a PTM hierarchy
+**/
+STATIC
+VOID
+SetPtm (
+  IN     SBDF       Sbdf,
+  IN OUT UINT8      *EffectiveGranularity,
+  IN OUT BOOLEAN    *PtmHierarchy
+  )
+{
+  PTM_CTRL CurrentPtmCtrl;
+  PTM_CAPS CurrentPtmCaps;
+  PTM_CTRL OrigPtmCtrl;
+  UINT16   PtmCapHeaderOffset;
+
+  PtmCapHeaderOffset = PcieFindExtendedCapId ((UINT8) Sbdf.Seg, (UINT8) Sbdf.Bus, (UINT8) Sbdf.Dev, (UINT8) Sbdf.Func, V_PCIE_EX_PTM_CID);
+  CurrentPtmCtrl = GetPtmControl (Sbdf, PtmCapHeaderOffset);
+  CurrentPtmCaps = GetPtmCapability (Sbdf, PtmCapHeaderOffset);
+
+  OrigPtmCtrl.Uint32 = CurrentPtmCtrl.Uint32;
+
+  if ( (*PtmHierarchy == FALSE) && CurrentPtmCaps.Bits.RootCapable) {
+    // Select device as PTM Root if PTM Root is not selected.
+    CurrentPtmCtrl.Bits.RootSelect = TRUE;
+    *EffectiveGranularity = (UINT8) CurrentPtmCaps.Bits.LocalClockGranularity;
+    *PtmHierarchy = TRUE;
+  }
+
+  if (*PtmHierarchy == TRUE) {
+    // Enable PTM if device is part of a ptm hierarchy
+    CurrentPtmCtrl.Bits.Enable = TRUE;
+
+    if (CurrentPtmCaps.Bits.RequesterCapable) {
+      // Set Effective Granularity if PTM device is Requester roles.
+      CurrentPtmCtrl.Bits.EffectiveGranularity = *EffectiveGranularity;
+    }
+  }
+
+  if (OrigPtmCtrl.Uint32 != CurrentPtmCtrl.Uint32) {
+    SetPtmControl (Sbdf, PtmCapHeaderOffset, CurrentPtmCtrl);
+  }
+
+  // Update EffectiveGranularity.
+  // Set to zero if 1 or more switches between the root and endpoint report local granularity = 0.
+  // Otherwise set to the max local granularity of the hierarchy.
+  if ( ((CurrentPtmCaps.Bits.LocalClockGranularity == 0) && CurrentPtmCaps.Bits.RequesterCapable) ||
+       (*EffectiveGranularity  == 0) ) {
+    *EffectiveGranularity = 0;
+  } else {
+    *EffectiveGranularity = MAX (*EffectiveGranularity, (UINT8) CurrentPtmCaps.Bits.LocalClockGranularity);
+  }
+}
+
+/**
+  Configures PTM hierarchies by searching for Endpoints and Upstream Switches
+  that are PTM capable. Each PTM device role is identified and configured accordingly.
+  PTM root capable devices are selected as PTM root if the device is not already in a
+  PTM hierarchy.
+  PTM capable Root Ports must be configured before calling this function.
+  @note: This function has not been tested with switches.
+
+  @param[in] Sbdf                 Address of curretly visited Pcie device
+  @param[in] EffectiveGranularity The largest Clock Granularity from Upstream Devices
+  @param[in] PtmHierarchy         TRUE = Device in a PTM Hierarchy, FALSE = Not in PTM Hierarchy
+**/
+STATIC
+VOID
+RecursivePtmConfiguration (
+  SBDF          Sbdf,
+  UINT8         EffectiveGranularity,
+  BOOLEAN       PtmHierarchy
+  )
+{
+  SBDF         ChildSbdf;
+  PCI_DEV_TYPE DevType;
+
+  DEBUG ((DEBUG_INFO, "RecursivePtmConfiguration %x:%x:%x\n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func));
+
+  DevType = GetDeviceType (Sbdf);
+
+  if (IsPtmCapable (Sbdf)) {
+    //
+    // Enable PTM for PTM Capable devices (Endpoints, Upstream Switch, and Root Ports).
+    // @Note: Switches have not been tested.
+    //
+    SetPtm (Sbdf, &EffectiveGranularity, &PtmHierarchy);
+  } else if (!IsPtmCapable (Sbdf) && (DevType == DevTypePcieUpstream) ) {
+    //
+    // Non-PTM UpStream Switch Ports breaks the PTM Hierarchy.
+    // No other downstream PTM devices should be PTM enabled until a PTM Root capable device is selected.
+    //
+    PtmHierarchy = FALSE;
+    EffectiveGranularity = 0;
+  }
+
+  if (HasChildBus (Sbdf, &ChildSbdf)) {
+    while (FindNextPcieChild (DevType, &ChildSbdf)) {
+      RecursivePtmConfiguration (ChildSbdf, EffectiveGranularity, PtmHierarchy);
+    }
+  }
+}
+
+/**
+  Initializes the following features in rootport and devices behind it:
+  Maximum Payload Size (generic)
+  Rootport packet split (proprietary)
+  EonOfInterrupt forwarding (proprietary)
+  Common Clock Configuration (generic)
+
+  Generic: any code written according to PCIE Express base specification can do that.
+  Proprietary: code uses registers and features that are specific to Intel silicon
+  and probably only this Reference Code knows how to handle that.
+
+  If OEM implemented generic feature enabling in his platform code or trusts Operating System
+  to do it, then those features can be deleted from here.
+
+  CCC requires link retrain, which takes a while. CCC must happen before L0s/L1 programming.
+  If there was guarantee no code would access PCI while links retrain, it would be possible to skip this waiting
+
+  @param[in] RpSegment  address of rootport on PCIe
+  @param[in] RpBus      address of rootport on PCIe
+  @param[in] RpDevice   address of rootport on PCIe
+  @param[in] RpFunction address of rootport on PCIe
+  @param[in] BusMin     minimum Bus number that can be assigned below this rootport
+  @param[in] BusMax     maximum Bus number that can be assigned below this rootport
+**/
+VOID
+RootportDownstreamConfiguration (
+  UINT8                     RpSegment,
+  UINT8                     RpBus,
+  UINT8                     RpDevice,
+  UINT8                     RpFunction,
+  UINT8                     BusMin,
+  UINT8                     BusMax,
+  PCI_SKU                   PciSku
+  )
+{
+  UINT8           Mps;
+  BOOLEAN         IoApicPresent;
+  UINT64          RpBase;
+  SBDF            RpSbdf;
+  SBDF_TABLE      BridgeCleanupList;
+
+  IoApicPresent = FALSE;
+  RpBase = PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, 0);
+  if (!(IsDevicePresent (RpBase))) {
+    return;
+  }
+  RpSbdf.Seg = RpSegment;
+  RpSbdf.Bus = RpBus;
+  RpSbdf.Dev = RpDevice;
+  RpSbdf.Func = RpFunction;
+  RpSbdf.PcieCap = PcieBaseFindCapId (RpBase, EFI_PCI_CAPABILITY_ID_PCIEXP);
+
+  DEBUG ((DEBUG_INFO, "RootportDownstreamConfiguration %x:%x\n", RpDevice, RpFunction));
+  BridgeCleanupList.Count = 0;
+  RecursiveBusAssignment (RpSbdf, BusMin, BusMax, &BridgeCleanupList);
+
+  Mps = RecursiveMpsCheck (RpSbdf);
+  RecursiveMpsConfiguration (RpSbdf, Mps);
+  if (PciSku == EnumPchPcie) {
+    RpBase = SbdfToBase (RpSbdf);
+    ConfigureRpPacketSplit(RpBase, Mps);
+    IoApicPresent = RecursiveIoApicCheck(RpSbdf);
+  }
+  if ((PciSku == EnumPchPcie) || (PciSku == EnumCpuPcie)) {
+    ConfigureEoiForwarding (RpBase, IoApicPresent);
+  }
+  RecursiveCccConfiguration (RpSbdf, TRUE);
+
+  if (IsPtmCapable (RpSbdf)) {
+    RecursivePtmConfiguration (RpSbdf, 0, FALSE);
+  }
+
+  ClearBusFromTable (&BridgeCleanupList);
+}
+
+/**
+  Checks if given PCI device is capable of Latency Tolerance Reporting
+
+  @param[in] Sbdf            device's segment:bus:device:function coordinates
+
+  @retval TRUE if yes
+**/
+BOOLEAN
+IsLtrCapable (
+  SBDF Sbdf
+  )
+{
+  if (Sbdf.PcieCap == 0) {
+    return FALSE;
+  }
+  return !!(PciSegmentRead32 (SbdfToBase (Sbdf) + Sbdf.PcieCap + R_PCIE_DCAP2_OFFSET) & B_PCIE_DCAP2_LTRMS);
+}
+
+/**
+  Returns combination of two LTR override values
+  The resulting LTR override separately chooses stricter limits for snoop and nosnoop
+
+  @param[in] LtrA      LTR override values to be combined
+  @param[in] LtrB      LTR override values to be combined
+
+  @retval LTR override value
+**/
+LTR_OVERRIDE
+CombineLtr (
+  LTR_OVERRIDE LtrA,
+  LTR_OVERRIDE LtrB
+  )
+{
+  UINT64        DecodedLatencyA;
+  UINT64        DecodedLatencyB;
+  LTR_OVERRIDE  Result;
+  static UINT32 ScaleEncoding [8] = {1, 32, 1024, 32768, 1048576, 33554432, 0, 0};
+
+  ZeroMem (&Result, sizeof (LTR_OVERRIDE));
+  DecodedLatencyA = ScaleEncoding[LtrA.MaxSnoopLatencyScale] * LtrA.MaxSnoopLatencyValue;
+  DecodedLatencyB = ScaleEncoding[LtrB.MaxSnoopLatencyScale] * LtrB.MaxSnoopLatencyValue;
+  if ((!LtrB.MaxSnoopLatencyRequirement) || ((DecodedLatencyA < DecodedLatencyB) && LtrA.MaxSnoopLatencyRequirement)) {
+    Result.MaxSnoopLatencyValue       = LtrA.MaxSnoopLatencyValue;
+    Result.MaxSnoopLatencyScale       = LtrA.MaxSnoopLatencyScale;
+    Result.MaxSnoopLatencyRequirement = LtrA.MaxSnoopLatencyRequirement;
+  } else {
+    Result.MaxSnoopLatencyValue       = LtrB.MaxSnoopLatencyValue;
+    Result.MaxSnoopLatencyScale       = LtrB.MaxSnoopLatencyScale;
+    Result.MaxSnoopLatencyRequirement = LtrB.MaxSnoopLatencyRequirement;
+  }
+  DecodedLatencyA = ScaleEncoding[LtrA.MaxNoSnoopLatencyScale] * LtrA.MaxNoSnoopLatencyValue;
+  DecodedLatencyB = ScaleEncoding[LtrB.MaxNoSnoopLatencyScale] * LtrB.MaxNoSnoopLatencyValue;
+  if ((!LtrB.MaxNoSnoopLatencyRequirement) || ((DecodedLatencyA < DecodedLatencyB) && LtrA.MaxNoSnoopLatencyRequirement)) {
+    Result.MaxNoSnoopLatencyValue       = LtrA.MaxNoSnoopLatencyValue;
+    Result.MaxNoSnoopLatencyScale       = LtrA.MaxNoSnoopLatencyScale;
+    Result.MaxNoSnoopLatencyRequirement = LtrA.MaxNoSnoopLatencyRequirement;
+  } else {
+    Result.MaxNoSnoopLatencyValue       = LtrB.MaxNoSnoopLatencyValue;
+    Result.MaxNoSnoopLatencyScale       = LtrB.MaxNoSnoopLatencyScale;
+    Result.MaxNoSnoopLatencyRequirement = LtrB.MaxNoSnoopLatencyRequirement;
+  }
+  if (LtrA.ForceOverride || LtrB.ForceOverride) {
+    Result.ForceOverride = TRUE;
+  }
+  DEBUG ((DEBUG_INFO, "CombineLtr: A(V%d S%d E%d : V%d S%d E%d, F%d)\n",
+    LtrA.MaxSnoopLatencyValue, LtrA.MaxSnoopLatencyScale, LtrA.MaxSnoopLatencyRequirement,
+    LtrA.MaxNoSnoopLatencyValue, LtrA.MaxNoSnoopLatencyScale, LtrA.MaxNoSnoopLatencyRequirement,
+    LtrA.ForceOverride
+    ));
+  DEBUG ((DEBUG_INFO, "          : B(V%d S%d E%d : V%d S%d E%d, F%d)\n",
+    LtrB.MaxSnoopLatencyValue, LtrB.MaxSnoopLatencyScale, LtrB.MaxSnoopLatencyRequirement,
+    LtrB.MaxNoSnoopLatencyValue, LtrB.MaxNoSnoopLatencyScale, LtrB.MaxNoSnoopLatencyRequirement,
+    LtrB.ForceOverride
+    ));
+  DEBUG ((DEBUG_INFO, "          : R(V%d S%d E%d : V%d S%d E%d, F%d)\n",
+    Result.MaxSnoopLatencyValue, Result.MaxSnoopLatencyScale, Result.MaxSnoopLatencyRequirement,
+    Result.MaxNoSnoopLatencyValue, Result.MaxNoSnoopLatencyScale, Result.MaxNoSnoopLatencyRequirement,
+    Result.ForceOverride
+    ));
+  return Result;
+}
+
+/**
+  Returns LTR override value for given device
+  The value is extracted from Device Override table. If the device is not found,
+  the returned value will have Requirement bits clear
+
+  @param[in] Base            device's base address
+  @param[in] Override        device override table
+
+  @retval LTR override value
+**/
+LTR_OVERRIDE
+GetOverrideLtr (
+  UINT64         Base,
+  OVERRIDE_TABLE *Override
+  )
+{
+  UINT16       DevId;
+  UINT16       VenId;
+  UINT16       RevId;
+  UINT32       Index;
+  LTR_OVERRIDE ReturnValue = {0};
+
+  VenId = PciSegmentRead16 (Base + PCI_VENDOR_ID_OFFSET);
+  DevId = PciSegmentRead16 (Base + PCI_DEVICE_ID_OFFSET);
+  RevId = PciSegmentRead16 (Base + PCI_REVISION_ID_OFFSET);
+
+  for (Index = 0; Index < Override->Size; Index++) {
+    if (((Override->Table[Index].OverrideConfig & PchPcieLtrOverride) == PchPcieLtrOverride) &&
+        (Override->Table[Index].VendorId == VenId) &&
+        ((Override->Table[Index].DeviceId == DevId) || (Override->Table[Index].DeviceId == 0xFFFF)) &&
+        ((Override->Table[Index].RevId == RevId) || (Override->Table[Index].RevId == 0xFF))) {
+      if (Override->Table[Index].SnoopLatency & 0x8000) {
+        ReturnValue.MaxSnoopLatencyRequirement = 1;
+        ReturnValue.MaxSnoopLatencyValue = Override->Table[Index].SnoopLatency & 0x3FF;
+        ReturnValue.MaxSnoopLatencyScale = (Override->Table[Index].SnoopLatency & 0x1C00) >> 10;
+      }
+      if (Override->Table[Index].NonSnoopLatency & 0x8000) {
+        ReturnValue.MaxNoSnoopLatencyRequirement = 1;
+        ReturnValue.MaxNoSnoopLatencyValue = Override->Table[Index].NonSnoopLatency & 0x3FF;
+        ReturnValue.MaxNoSnoopLatencyScale = (Override->Table[Index].NonSnoopLatency & 0x1C00) >> 10;
+      }
+      ReturnValue.ForceOverride = Override->Table[Index].ForceLtrOverride;
+      break;
+    }
+  }
+  return ReturnValue;
+}
+
+/**
+  In accordance with PCIe spec, devices with no LTR support are considered to have no LTR requirements
+  which means infinite latency tolerance. This was found to cause problems with HID and Audio devices without LTR
+  support placed behind PCIe switches with LTR support, as Switch's upstream link would be allowed to enter L1.2
+  and cause large latency downstream. To work around such issues and to fix some devices with broken
+  LTR reporting, Device Override table was introduced.
+  This function scans PCIe tree for devices mentioned in override table and calculates the strictest
+  LTR requirement between them. That value will be programmed into rootport's LTR override register
+
+  This function expects that bridges have bus numbers already configured
+
+  @param[in] BusLimit                       maximum Bus number that can be assigned below this port
+  @param[in] Segment,Bus,Device,Function    address of currently visited PCIe device
+  @param[in] AspmOverride                   Device specific ASPM policy override items
+
+  @retval MaxLTR programmed in this device
+**/
+LTR_OVERRIDE
+RecursiveLtrOverrideCheck (
+  SBDF           Sbdf,
+  OVERRIDE_TABLE *AspmOverride
+  )
+{
+  UINT64       Base;
+  SBDF         ChildSbdf;
+  LTR_OVERRIDE MyLtrOverride;
+  LTR_OVERRIDE ChildLtr;
+  PCI_DEV_TYPE DevType;
+
+  DEBUG ((DEBUG_INFO, "RecursiveLtrOverrideCheck %x:%x:%x\n", Sbdf.Bus, Sbdf.Dev, Sbdf.Func));
+
+  Base = SbdfToBase(Sbdf);
+
+  MyLtrOverride = GetOverrideLtr (Base, AspmOverride);
+  if (HasChildBus (Sbdf, &ChildSbdf)) {
+    DevType = GetDeviceType (Sbdf);
+    while (FindNextPcieChild (DevType, &ChildSbdf)) {
+      ChildLtr = RecursiveLtrOverrideCheck (ChildSbdf, AspmOverride);
+      MyLtrOverride = CombineLtr (MyLtrOverride, ChildLtr);
+    }
+  }
+  return MyLtrOverride;
+}
+
+/**
+  Configures the following power-management related features in rootport and devices behind it:
+  LTR limit (generic)
+  LTR override (proprietary)
+  Clock Power Management (generic)
+  L1 substates (generic except for the override table)
+  L1.LOW substate (proprietary)
+  L0s and L1 (generic)
+
+  Generic: any code written according to PCIE Express base specification can do that.
+  Proprietary: code uses registers and features that are specific to Intel silicon
+  and probably only this Reference Code knows how to handle that.
+
+  If OEM implemented generic feature enabling in his platform code or trusts Operating System
+  to do it, then those features can be deleted from here.
+
+  @param[in] RpSegment                address of rootport on PCIe
+  @param[in] RpBus                    address of rootport on PCIe
+  @param[in] RpDevice                 address of rootport on PCIe
+  @param[in] RpFunction               address of rootport on PCIe
+  @param[in] BusLimit                 maximum Bus number that can be assigned below this rootport
+  @param[in] PcieRpLtrConfig          address of LTR Policy struct
+  @param[in] PcieRpCommonConfig       address of Common PCIe Policy struct
+  @param[in] AspmOverrideTableSize    size of override array
+  @param[in] AspmOverrideTable        array of device that need exceptions in configuration
+**/
+VOID
+RootportDownstreamPmConfiguration (
+  UINT8                               RpSegment,
+  UINT8                               RpBus,
+  UINT8                               RpDevice,
+  UINT8                               RpFunction,
+  UINT8                               BusMin,
+  UINT8                               BusMax,
+  PCIE_ROOT_PORT_COMMON_CONFIG        *PcieRpCommonConfig,
+  UINT32                              AspmOverrideTableSize,
+  PCH_PCIE_DEVICE_OVERRIDE            *AspmOverrideTable
+  )
+{
+  LTR_LIMIT      PolicyLtr;
+  LTR_OVERRIDE   TreeLtr;
+  OVERRIDE_TABLE PmOverrideTable;
+  UINT64         RpBase;
+  SBDF           RpSbdf;
+  SBDF_TABLE     BridgeCleanupList;
+
+  RpBase = PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, 0);
+  if (!(IsDevicePresent (RpBase))) {
+    return;
+  }
+  PmOverrideTable.Size = AspmOverrideTableSize;
+  PmOverrideTable.Table = AspmOverrideTable;
+
+  DEBUG ((DEBUG_INFO, "RootportDownstreamPmConfiguration %x:%x\n", RpDevice, RpFunction));
+  PolicyLtr.MaxNoSnoopLatencyScale = (PcieRpCommonConfig->PcieRpLtrConfig.LtrMaxNoSnoopLatency & 0x1c00) >> 10;
+  PolicyLtr.MaxNoSnoopLatencyValue = PcieRpCommonConfig->PcieRpLtrConfig.LtrMaxNoSnoopLatency & 0x3FF;
+  PolicyLtr.MaxSnoopLatencyScale   = (PcieRpCommonConfig->PcieRpLtrConfig.LtrMaxSnoopLatency & 0x1c00) >> 10;
+  PolicyLtr.MaxSnoopLatencyValue   = PcieRpCommonConfig->PcieRpLtrConfig.LtrMaxSnoopLatency & 0x3FF;
+
+  RpSbdf.Seg = RpSegment;
+  RpSbdf.Bus = RpBus;
+  RpSbdf.Dev = RpDevice;
+  RpSbdf.Func = RpFunction;
+  RpSbdf.PcieCap = PcieBaseFindCapId (RpBase, EFI_PCI_CAPABILITY_ID_PCIEXP);
+  //
+  // This code could execute either before or after enumeration. If before, then buses would not yet be assigned to bridges,
+  // making devices deeper in the hierarchy inaccessible.
+  // RecursiveBusAssignment will scan whole PCie tree and assign bus numbers to uninitialized bridges, if there are any
+  // List of such bridges will be kept in CleanupList, so that after PM programming is done, bus numbers can brought to original state
+  //
+  BridgeCleanupList.Count = 0;
+  RecursiveBusAssignment(RpSbdf, BusMin, BusMax, &BridgeCleanupList);
+  //
+  // The 'Recursive...' functions below expect bus numbers to be already assigned
+  //
+  RecursiveLtrConfiguration (RpSbdf, PolicyLtr);
+  TreeLtr = RecursiveLtrOverrideCheck (RpSbdf, &PmOverrideTable);
+  ConfigureRpLtrOverride (RpBase, RpSbdf.Dev, &TreeLtr, &(PcieRpCommonConfig->PcieRpLtrConfig));
+  DEBUG ((DEBUG_INFO, "ConfigureRpLtrOverride %x:%x\n", RpSbdf.Dev, RpSbdf.Func));
+  if (PcieRpCommonConfig->EnableCpm) {
+    RecursiveCpmConfiguration (RpSbdf);
+  }
+  //
+  // L1 substates can be modified only when L1 is disabled, so this function must execute
+  // before Aspm configuration which enables L1
+  //
+  RecursiveL1ssConfiguration (RpSbdf, &PmOverrideTable);
+  L1ssProprietaryConfiguration (RpBase, IsLtrCapable (RpSbdf));
+  RecursiveAspmConfiguration (RpSbdf, 0, &PmOverrideTable);
+
+  ClearBusFromTable (&BridgeCleanupList);
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/PciExpressHelpersLibrary/PciExpressHelpersLibrary.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/PciExpressHelpersLibrary/PciExpressHelpersLibrary.h
new file mode 100644
index 0000000000..19c1051771
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/PciExpressHelpersLibrary/PciExpressHelpersLibrary.h
@@ -0,0 +1,40 @@
+/** @file
+  Header file for Pci Express helps library implementation.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCI_EXPRESS_HELPERS_LIBRARY_H_
+#define _PCI_EXPRESS_HELPERS_LIBRARY_H_
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <IndustryStandard/Pci.h>
+#include <PchPolicyCommon.h>
+#include <Library/PchPcieRpLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PciExpressHelpersLib.h>
+#include <Library/PcieRpLib.h>
+#include <PcieRegs.h>
+#include <Register/CpuPcieRegs.h>
+#include <Register/PchPcieRpRegs.h>
+
+#define LTR_VALUE_MASK (BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5 + BIT6 + BIT7 + BIT8 + BIT9)
+#define LTR_SCALE_MASK (BIT10 + BIT11 + BIT12)
+
+  #define CONFIG_WRITE_LOOP_COUNT   100000
+
+//
+// LTR related macros
+//
+#define LTR_LATENCY_VALUE(x)           ((x) & LTR_VALUE_MASK)
+#define LTR_SCALE_VALUE(x)             (((x) & LTR_SCALE_MASK) >> 10)
+#define LTR_LATENCY_NS(x)              (LTR_LATENCY_VALUE(x) * (1 << (5 * LTR_SCALE_VALUE(x))))
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/PciExpressHelpersLibrary/PeiDxeSmmPciExpressHelpersLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/PciExpressHelpersLibrary/PeiDxeSmmPciExpressHelpersLib.inf
new file mode 100644
index 0000000000..8f673d14c2
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/PciExpressHelpersLibrary/PeiDxeSmmPciExpressHelpersLib.inf
@@ -0,0 +1,49 @@
+## @file
+# Component description file for the PeiDxeSmmPciExpressHelpersLib
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+  INF_VERSION = 0x00010017
+  BASE_NAME = PeiDxeSmmPciExpressHelpersLib
+  FILE_GUID = 07E3F76D-6D26-419d-9053-58696A15B519
+  VERSION_STRING = 1.0
+  MODULE_TYPE = BASE
+LIBRARY_CLASS = PciExpressHelpersLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+
+
+
+[LibraryClasses]
+  IoLib
+  DebugLib
+  PchPcieRpLib
+  PchPcrLib
+  PchInfoLib
+  GpioLib
+  TimerLib
+  BasePcieHelperLib
+  PchPciBdfLib
+  HobLib
+  PcieRpLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+  PciExpressHelpersLibrary.c
+  PciExpressHelpersLibrary.h
+
+[Guids]
+  gCpuPcieHobGuid
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/PcieClientRpLib/PcieClientRpLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/PcieClientRpLib/PcieClientRpLib.c
new file mode 100644
index 0000000000..15d295a573
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/PcieClientRpLib/PcieClientRpLib.c
@@ -0,0 +1,247 @@
+/** @file
+  This file contains routines that support PCI Express initialization
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Uefi/UefiBaseType.h>
+#include <IndustryStandard/Pci.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PcieHelperLib.h>
+#include <Library/PchSbiAccessLib.h>
+#include <Library/PchPciBdfLib.h>
+#include <Library/PcieRpLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchPcieRpLib.h>
+#include <Library/PsfLib.h>
+#include <Library/HobLib.h>
+#include <Register/PchPcieRpRegs.h>
+#include <Register/PcieSipRegs.h>
+#include <PcieRegs.h>
+#include <PchPcieRpInfo.h>
+#include <CpuPcieInfo.h>
+#include <CpuPcieHob.h>
+
+/**
+  Get PCIe port number for enabled port.
+  @param[in] RpBase    Root Port pci segment base address
+
+  @retval Root Port number (1 based)
+**/
+UINT32
+PciePortNum (
+  IN     UINT64  RpBase
+  )
+{
+  return PciSegmentRead32 (RpBase + R_PCH_PCIE_CFG_LCAP) >> N_PCH_PCIE_CFG_LCAP_PN;
+}
+
+/**
+  Get PCIe root port index
+
+  @param[in] RpBase    Root Port pci segment base address
+
+  @retval Root Port index (0 based)
+**/
+UINT32
+PciePortIndex (
+  IN     UINT64  RpBase
+  )
+{
+  return PciePortNum (RpBase) - 1;
+}
+
+/**
+  This function checks whether PHY lane power gating is enabled on the port.
+
+  @param[in] RpBase                 Root Port base address
+
+  @retval TRUE                      PHY power gating is enabled
+  @retval FALSE                     PHY power gating disabled
+**/
+BOOLEAN
+PcieIsPhyLanePgEnabled (
+  IN     UINT64  RpBase
+  )
+{
+  UINT32 Data32;
+
+  Data32 = PciSegmentRead32 (RpBase + R_PCH_PCIE_CFG_PCIEPMECTL);
+  return (Data32 & B_PCH_PCIE_CFG_PCIEPMECTL_DLSULPPGE) != 0;
+}
+
+/**
+  Configures Root Port packet split.
+
+  @param[in] Segment,Bus,Device,Function    address of currently visited PCIe device
+  @param[in] Mps                            maximum packet size
+**/
+VOID
+ConfigureRpPacketSplit (
+  UINT64 RpBase,
+  UINT8  Mps
+  )
+{
+  PciSegmentAndThenOr32 (RpBase + R_PCIE_CFG_CCFG, (UINT32) ~(B_PCIE_CFG_CCFG_UNRS), Mps << N_PCIE_CFG_CCFG_UNRS);
+}
+
+/**
+  Configures LTR override in Root Port's proprietary registers.
+
+  @param[in] Segment,Bus,Device,Function    address of currently visited PCIe device
+  @param[in] DevNum                         currently visited device number
+  @param[in] RpConfig                       Root Port LTR configuration
+  @param[in] AspmOverride                   combination of LTR override values from all devices under this Root Port
+**/
+VOID
+ConfigureRpLtrOverride (
+  UINT64           RpBase,
+  UINT32           DevNum,
+  LTR_OVERRIDE     *TreeLtr,
+  PCIE_LTR_CONFIG  *LtrConfig
+  )
+{
+  UINT32       OvrEn;
+  UINT32       OvrVal;
+  BOOLEAN      IsCpuPcie;
+  UINT32       LtrCfgLock;
+
+  IsCpuPcie = FALSE;
+  OvrEn = 0;
+  OvrVal = 0;
+  LtrCfgLock = 0;
+
+  if (DevNum == SA_PEG0_DEV_NUM || DevNum == SA_PEG3_DEV_NUM) {
+    IsCpuPcie = TRUE;
+  }
+
+  //
+  // LTR settings from LTROVR register only get acknowledged on rising edge of LTROVR2[1:0]
+  // If those bits were already set (that can happen on a plug-hotUnplug-hotPlug scenario),
+  // they need to be toggled
+  //
+  if (PciSegmentRead32 (RpBase + R_PCH_PCIE_CFG_LTROVR2) != 0) {
+    PciSegmentWrite32 (RpBase + R_PCH_PCIE_CFG_LTROVR2, 0);
+  }
+  //
+  // (*)LatencyOverrideMode = 0 -> no override
+  //                          1 -> override with RP policy values
+  //                          2 -> override with endpoint's override values
+  //
+
+  if (LtrConfig->ForceLtrOverride || TreeLtr->ForceOverride) {
+    OvrEn |= B_PCH_PCIE_CFG_LTROVR2_FORCE_OVERRIDE;
+  }
+  if (LtrConfig->LtrConfigLock == TRUE) {
+    OvrEn |= B_PCH_PCIE_CFG_LTROVR2_LOCK;
+  }
+
+  if (LtrConfig->SnoopLatencyOverrideMode == 1) {
+    OvrEn |= B_PCH_PCIE_CFG_LTROVR2_LTRSOVREN;
+    OvrVal |= LtrConfig->SnoopLatencyOverrideValue;
+    OvrVal |= LtrConfig->SnoopLatencyOverrideMultiplier << 10;
+    OvrVal |= B_PCH_PCIE_CFG_LTROVR_LTRSROVR;
+  } else if (LtrConfig->SnoopLatencyOverrideMode == 2) {
+    if (TreeLtr->MaxSnoopLatencyRequirement) {
+      OvrEn |= B_PCH_PCIE_CFG_LTROVR2_LTRSOVREN;
+      OvrVal |= TreeLtr->MaxSnoopLatencyValue;
+      OvrVal |= TreeLtr->MaxSnoopLatencyScale << 10;
+      OvrVal |= B_PCH_PCIE_CFG_LTROVR_LTRSROVR;
+    }
+  }
+  if (LtrConfig->NonSnoopLatencyOverrideMode == 1) {
+    OvrEn |= B_PCH_PCIE_CFG_LTROVR2_LTRNSOVREN;
+    OvrVal |= LtrConfig->NonSnoopLatencyOverrideValue << 16;
+    OvrVal |= LtrConfig->NonSnoopLatencyOverrideMultiplier << 26;
+    OvrVal |= B_PCH_PCIE_CFG_LTROVR_LTRNSROVR;
+  } else if (LtrConfig->NonSnoopLatencyOverrideMode == 2) {
+    if (TreeLtr->MaxNoSnoopLatencyRequirement) {
+      OvrEn |= B_PCH_PCIE_CFG_LTROVR2_LTRNSOVREN;
+      OvrVal |= TreeLtr->MaxNoSnoopLatencyValue << 16;
+      OvrVal |= TreeLtr->MaxNoSnoopLatencyScale << 26;
+      OvrVal |= B_PCH_PCIE_CFG_LTROVR_LTRNSROVR;
+    }
+  }
+  PciSegmentWrite32 (RpBase + R_PCH_PCIE_CFG_LTROVR, OvrVal);
+  PciSegmentWrite32 (RpBase + R_PCH_PCIE_CFG_LTROVR2, OvrEn);
+
+  DEBUG ((DEBUG_INFO, "ConfigureRpLtrOverride IsCpuPcie=%d\n", IsCpuPcie));
+  DEBUG ((DEBUG_INFO, "ConfigureRpLtrOverride %x Val %x En %x\n", RpBase, OvrVal, OvrEn));
+}
+
+/**
+  This function configures EOI message forwarding for PCIe port.
+  If there's an IoAPIC behind this port, forwarding will be enabled
+  Otherwise it will be disabled to minimize bus traffic
+
+  @param[in] Segment,Bus,Device,Function    address of currently visited PCIe device
+  @param[in] IoApicPresent  TRUE if there's IoAPIC behind this Root Port
+**/
+VOID
+ConfigureEoiForwarding (
+  UINT64   RpBase,
+  BOOLEAN  IoApicPresent
+  )
+{
+  UINT32 RpIndex;
+
+  RpIndex = PciePortIndex (RpBase);
+
+  if (IoApicPresent == FALSE) {
+   PciSegmentOr32 (RpBase + R_PCH_PCIE_CFG_MPC2, B_PCH_PCIE_CFG_MPC2_EOIFD);
+  } else {
+    ///
+    /// If there is an IOAPIC discovered behind Root Port, program PSF Multicast registers
+    /// in accordance with PCH PCIe BWG  PSF EOI Multicast Configuration
+    ///
+    PciSegmentAnd32 (RpBase + R_PCH_PCIE_CFG_MPC2, (UINT32)~B_PCH_PCIE_CFG_MPC2_EOIFD);
+    PsfConfigurEoiForPciePort (RpIndex);
+  }
+}
+
+/**
+  Configures proprietary parts of L1 substates configuration in Root Port
+
+  @param[in] RpSbdf       segment:bus:device:function coordinates of Root Port
+  @param[in] LtrCapable   TRUE if Root Port is LTR capable
+**/
+VOID
+L1ssProprietaryConfiguration (
+  UINT64  RpBase,
+  BOOLEAN LtrCapable
+  )
+{
+  BOOLEAN ClkreqSupported;
+  BOOLEAN L1ssEnabled;
+  UINT16  PcieCapOffset;
+  UINT32  Data32;
+  BOOLEAN L1LowSupported;
+
+  ClkreqSupported = PcieIsPhyLanePgEnabled (RpBase);
+
+  PcieCapOffset = PcieBaseFindExtendedCapId (RpBase, V_PCIE_EX_L1S_CID);
+  if (PcieCapOffset == 0) {
+    L1ssEnabled = FALSE;
+  } else {
+    Data32 = PciSegmentRead32 (RpBase + PcieCapOffset + R_PCIE_EX_L1SCTL1_OFFSET);
+    L1ssEnabled = Data32 & (B_PCIE_EX_L1SCAP_AL1SS | B_PCIE_EX_L1SCAP_AL12S | B_PCIE_EX_L1SCAP_PPL11S |B_PCIE_EX_L1SCAP_PPL12S);
+  }
+  L1LowSupported = ClkreqSupported && LtrCapable && !L1ssEnabled;
+
+  ///
+  /// If L1.SNOOZ and L1.OFF (L1 Sub-States) are not supported and per-port CLKREQ# is supported, and LTR is supported:
+  /// Enable L1.LOW by setting Dxx:Fn:420[17] = 1b
+  ///
+  if (L1LowSupported) {
+    PciSegmentOr32 (RpBase + R_PCH_PCIE_CFG_PCIEPMECTL, (UINT32) B_PCH_PCIE_CFG_PCIEPMECTL_L1LE);
+  } else {
+    PciSegmentAnd32 (RpBase + R_PCH_PCIE_CFG_PCIEPMECTL, (UINT32) ~B_PCH_PCIE_CFG_PCIEPMECTL_L1LE);
+  }
+
+  if (L1LowSupported || L1ssEnabled) {
+    ///
+    /// f.  Set Dxx:Fn:420h[0] to 1b prior to L1 enabling if any L1substate is enabled (including L1.LOW)
+    ///
+    PciSegmentOr32 (RpBase + R_PCH_PCIE_CFG_PCIEPMECTL, B_PCH_PCIE_CFG_PCIEPMECTL_L1FSOE);
+  }
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/PcieClientRpLib/PcieClientRpLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/PcieClientRpLib/PcieClientRpLib.inf
new file mode 100644
index 0000000000..86dceb14ee
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/PcieRp/LibraryPrivate/PcieClientRpLib/PcieClientRpLib.inf
@@ -0,0 +1,43 @@
+## @file
+# Component description file for the PcieClientRpLib
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+  INF_VERSION = 0x00010017
+  BASE_NAME = PcieClientRpLib
+  FILE_GUID = 77EB467D-674C-4C20-A13E-381600E182C4
+  VERSION_STRING = 1.0
+  MODULE_TYPE = BASE
+  LIBRARY_CLASS = PcieRpLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+
+
+[LibraryClasses]
+  IoLib
+  DebugLib
+  PchPcieRpLib
+  PchPcrLib
+  PchInfoLib
+  GpioLib
+  TimerLib
+  PsfLib
+  BasePcieHelperLib
+  PchPciBdfLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+  PcieClientRpLib.c
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 24/40] TigerlakeSiliconPkg/IpBlock: Add Pmc component
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (21 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 23/40] TigerlakeSiliconPkg/IpBlock: Add PcieRp component Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 25/40] TigerlakeSiliconPkg/IpBlock: Add Psf component Heng Luo
                   ` (15 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * IpBlock/Pmc/IncludePrivate
  * IpBlock/Pmc/Library
  * IpBlock/Pmc/LibraryPrivate

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/IncludePrivate/Library/PmcPrivateLib.h                                 | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/IncludePrivate/Register/PmcRegsVer2.h                                  |  52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/Library/PeiDxeSmmPmcLib/PeiDxeSmmPmcLib.inf                            |  42 ++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/Library/PeiDxeSmmPmcLib/PmcLib.c                                       | 545 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibVer2.inf   |  39 +++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibWithS3.inf |  40 ++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PmcPrivateLib.c                  | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PmcPrivateLibWithS3.c            | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 1126 insertions(+)

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


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 25/40] TigerlakeSiliconPkg/IpBlock: Add Psf component
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (22 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 24/40] TigerlakeSiliconPkg/IpBlock: Add Pmc component Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 26/40] TigerlakeSiliconPkg/IpBlock: Add Sata component Heng Luo
                   ` (14 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * IpBlock/Psf/IncludePrivate
  * IpBlock/Psf/LibraryPrivate

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Psf/IncludePrivate/Library/PsfLib.h               | 520 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Psf/LibraryPrivate/PsfLib/PeiDxeSmmPsfLibVer2.inf |  40 ++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Psf/LibraryPrivate/PsfLib/PsfLib.c                | 203 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Psf/LibraryPrivate/PsfLib/PsfLibInternal.h        | 470 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Psf/LibraryPrivate/PsfLib/PsfLibVer2.c            | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 1348 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Psf/IncludePrivate/Library/PsfLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Psf/IncludePrivate/Library/PsfLib.h
new file mode 100644
index 0000000000..f333be48d2
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Psf/IncludePrivate/Library/PsfLib.h
@@ -0,0 +1,520 @@
+/** @file
+  Header file for PchPsfPrivateLib.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_PSF_PRIVATE_LIB_H_
+#define _PCH_PSF_PRIVATE_LIB_H_
+
+#include <Library/PchPcrLib.h>
+#include <Register/PchPcrRegs.h>
+
+typedef struct {
+  UINT32       Id;
+  PCH_SBI_PID  SbPid;
+} PSF_SEGMENT;
+
+/**
+  Get list of supported PSF segments.
+
+  @param[out] PsfTable        Array of supported PSF segments
+  @param[out] PsfTableLength  Length of PsfTable
+**/
+VOID
+PsfSegments (
+  OUT PSF_SEGMENT  **PsfTable,
+  OUT UINT32       *PsfTableLength
+  );
+
+//
+// Structure for storing data on both PSF SideBand Port ID and
+// PSF port register offset for specific device
+//
+typedef struct {
+  PCH_SBI_PID  PsfPid;
+  UINT16       RegBase;
+} PSF_PORT;
+
+/**
+  Disable device at PSF level
+  Method not for bridges (e.g. PCIe Root Port)
+
+  @param[in] PsfPort  PSF PORT data structure
+**/
+VOID
+PsfDisableDevice (
+  IN PSF_PORT  PsfPort
+  );
+
+/**
+  Enable device at PSF level
+  Method not for bridges (e.g. PCIe Root Port)
+
+  @param[in] PsfPort  PSF PORT data structure
+**/
+VOID
+PsfEnableDevice (
+  IN PSF_PORT  PsfPort
+  );
+
+/**
+  Hide PciCfgSpace of device at PSF level
+  Method not for bridges (e.g. PCIe Root Port)
+
+  @param[in] PsfPort  PSF PORT data structure
+**/
+VOID
+PsfHideDevice (
+  IN PSF_PORT  PsfPort
+  );
+
+/**
+  Unhide PciCfgSpace of device at PSF level
+  Method not for bridges (e.g. PCIe Root Port)
+
+  @param[in] PsfPort  PSF PORT data structure
+**/
+VOID
+PsfUnhideDevice (
+  IN PSF_PORT  PsfPort
+  );
+
+/**
+  Disable device BARs at PSF level
+  Method not for bridges (e.g. PCIe Root Port)
+
+  @param[in] PsfPort     PSF PORT data structure
+  @param[in] BarDisMask  BIT0-BAR0, BIT1-BAR1,...
+                         Mask corresponds to 32bit wide BARs
+**/
+VOID
+PsfDisableDeviceBar (
+  IN PSF_PORT  PsfPort,
+  IN UINT32    BarDisMask
+  );
+
+/**
+  Enable device BARs at PSF level
+  Method not for bridges (e.g. PCIe Root Port)
+
+  @param[in] PsfPort     PSF PORT data structure
+  @param[in] BarEnMask   BIT0-BAR0, BIT1-BAR1,...
+                         Mask corresponds to 32bit wide BARs
+**/
+VOID
+PsfEnableDeviceBar (
+  IN PSF_PORT  PsfPort,
+  IN UINT32    BarEnMask
+  );
+
+/**
+  Disable IDER device at PSF level
+**/
+VOID
+PsfDisableIderDevice (
+  VOID
+  );
+
+/**
+  Enable SOL device at PSF level
+**/
+VOID
+PsfEnableSolDevice (
+  VOID
+  );
+
+/**
+  Disable SOL device at PSF level
+**/
+VOID
+PsfDisableSolDevice (
+  VOID
+  );
+
+/**
+  Set PMC ABASE value in PSF
+
+  @param[in] Address     Address for ACPI base.
+**/
+VOID
+PsfSetPmcAbase (
+  IN  UINT16       Address
+  );
+
+/**
+  Get PMC ABASE value from PSF
+
+  @retval Address     Address for ACPI base.
+**/
+UINT16
+PsfGetPmcAbase (
+  VOID
+  );
+
+/**
+  Get PMC PWRMBASE value from PSF
+
+  @retval Address     Address for PWRM base.
+**/
+UINT32
+PsfGetPmcPwrmBase (
+  VOID
+  );
+
+/**
+  Hide Cnvi WiFi device's PciCfgSpace at PSF level
+**/
+VOID
+PsfHideCnviWifiDevice (
+  VOID
+  );
+
+/**
+  Disable Cnvi Wifi device at PSF level
+**/
+VOID
+PsfDisableCnviWifiDevice (
+  VOID
+  );
+
+/**
+  Disable HDAudio device at PSF level
+**/
+VOID
+PsfDisableHdaDevice (
+  VOID
+  );
+
+/**
+  Disable Dsp bar at PSF level
+**/
+VOID
+PsfDisableDspBar (
+  VOID
+  );
+
+/**
+  Disable THC device at PSF level
+
+  @param[in]  ThcNumber                Touch Host Controller Number THC0 or THC1
+**/
+VOID
+PsfDisableThcDevice (
+  IN  UINT32        ThcNumber
+  );
+
+/**
+  Disable xDCI device at PSF level
+**/
+VOID
+PsfDisableXdciDevice (
+  VOID
+  );
+
+/**
+  Disable xHCI device at PSF level
+**/
+VOID
+PsfDisableXhciDevice (
+  VOID
+  );
+
+/**
+  Disable xHCI VTIO Phantom device at PSF level
+**/
+VOID
+PsfDisableXhciVtioDevice (
+  VOID
+  );
+
+/**
+  Disable SATA device at PSF level
+
+  @param[in]  SataCtrlIndex     SATA controller index
+**/
+VOID
+PsfDisableSataDevice (
+  IN UINT32     SataCtrlIndex
+  );
+
+/**
+  Return PSF_PORT for SCS eMMC device
+
+  @retval    PsfPort      PSF PORT structure for SCS eMMC device
+**/
+PSF_PORT
+PsfScsEmmcPort (
+  VOID
+  );
+
+/**
+  Return PSF_PORT for SCS SD Card device
+
+  @retval    PsfPort      PSF PORT structure for SCS SD Card device
+**/
+PSF_PORT
+PsfScsSdCardPort (
+  VOID
+  );
+
+/**
+  Return PSF_PORT for SCS UFS device
+
+  @param[in] UfsNum       UFS Device
+
+  @retval    PsfPort      PSF PORT structure for SCS UFS device
+**/
+PSF_PORT
+PsfScsUfsPort (
+  IN UINT32  UfsNum
+  );
+
+/**
+  Disable ISH device at PSF level
+**/
+VOID
+PsfDisableIshDevice (
+  VOID
+  );
+
+/**
+  Disable FPAK device at PSF level
+**/
+VOID
+PsfDisableFpakDevice (
+  VOID
+  );
+
+/**
+  Disable ISH BAR1 at PSF level
+**/
+VOID
+PsfDisableIshBar1 (
+  VOID
+  );
+
+/**
+  Disable GbE device at PSF level
+**/
+VOID
+PsfDisableGbeDevice (
+  VOID
+  );
+
+/**
+  Disable SMBUS device at PSF level
+**/
+VOID
+PsfDisableSmbusDevice (
+  VOID
+  );
+
+/**
+  Disable TraceHub ACPI devices at PSF level
+**/
+VOID
+PsfDisableTraceHubAcpiDevice (
+  VOID
+  );
+
+/**
+  Hide TraceHub ACPI devices PciCfgSpace at PSF level
+**/
+VOID
+PsfHideTraceHubAcpiDevice (
+  VOID
+  );
+
+/**
+  This procedure will hide TraceHub PciCfgSpace at PSF level
+**/
+VOID
+PsfHideTraceHubDevice (
+  VOID
+  );
+
+/**
+  This procedure will unhide TraceHub PciCfgSpace at PSF level
+**/
+VOID
+PsfUnhideTraceHubDevice (
+  VOID
+  );
+
+/**
+  This procedure will disable TraceHub device at PSF level
+**/
+VOID
+PsfDisableTraceHubDevice (
+  VOID
+  );
+
+/**
+  Configures rootspace 3 bus number for PCIe IMR use
+
+  @param[in] Rs3Bus        bus number
+**/
+VOID
+PsfSetRs3Bus (
+  UINT8 Rs3Bus
+  );
+
+/**
+  Disable PCIe Root Port at PSF level
+
+  @param[in] RpIndex        PCIe Root Port Index (0 based)
+**/
+VOID
+PsfDisablePcieRootPort (
+  IN UINT32  RpIndex
+  );
+
+/**
+  Program PSF grant counts for SATA
+  Call this before SATA ports are accessed for enumeration
+**/
+VOID
+PsfConfigureSataGrantCounts (
+  VOID
+  );
+
+/**
+  Specifies the root port configuration of the
+  PCIe controller. The number on the left of x
+  signifies the number of root ports in the controller
+  while value on the right is link width. N stands for
+  the number of PCIe lanes per root port instance.
+**/
+typedef enum {
+  PsfPcieCtrl4xn,
+  PsfPcieCtrl1x2n_2xn,
+  PsfPcieCtrl2xn_1x2n,
+  PsfPcieCtrl2x2n,
+  PsfPcieCtrl1x4n,
+  PsfPcieCtrlUndefined
+} PSF_PCIE_CTRL_CONFIG;
+
+/**
+  Program PSF grant counts for PCI express depending on controllers configuration
+
+  @param[in] PsfPcieCtrlConfigTable   Table with PCIe controllers configuration
+  @param[in] NumberOfPcieControllers  Number of PCIe controllers. This is also the size of PsfPcieCtrlConfig table
+**/
+VOID
+PsfConfigurePcieGrantCounts (
+  IN PSF_PCIE_CTRL_CONFIG  *PsfPcieCtrlConfigTable,
+  IN UINT32                NumberOfPcieControllers
+  );
+
+
+/**
+  This function enables EOI message forwarding in PSF for PCIe ports
+  for cases where IOAPIC is present behind this root port.
+
+  @param[in] RpIndex        Root port index (0 based)
+
+  @retval Status
+**/
+EFI_STATUS
+PsfConfigurEoiForPciePort (
+  IN  UINT32   RpIndex
+  );
+
+//
+// Structure for PSF Port Destination ID
+//
+typedef union {
+  UINT32 RegVal;
+  struct {
+    UINT32  ChannelId   : 8;  // Channel ID
+    UINT32  PortId      : 7;  // Port ID
+    UINT32  PortGroupId : 1;  // Port Group ID
+    UINT32  PsfId       : 8;  // PSF ID
+    UINT32  Rsvd        : 7;  // Reserved
+    UINT32  ChanMap     : 1;  // Channel map
+  } Fields;
+} PSF_PORT_DEST_ID;
+
+/**
+  PCIe PSF port destination ID (psf_id:port_group_id:port_id:channel_id)
+
+  @param[in] RpIndex        PCIe Root Port Index (0 based)
+
+  @retval Destination ID
+**/
+PSF_PORT_DEST_ID
+PsfPcieDestinationId (
+  IN UINT32 RpIndex
+  );
+
+/**
+  PSF early initialization.
+**/
+VOID
+PsfEarlyInit (
+  VOID
+  );
+
+/**
+  Assign new function number for PCIe Port Number.
+
+  @param[in] RpIndex        PCIe Root Port Index (0 based)
+  @param[in] NewFunction    New Function number
+**/
+VOID
+PsfSetPcieFunction (
+  IN UINT32  RpIndex,
+  IN UINT32  NewFunction
+  );
+
+/**
+  This function enables PCIe Relaxed Order in PSF
+**/
+VOID
+PsfEnablePcieRelaxedOrder (
+  VOID
+  );
+
+
+/**
+  Enable VTd support in PSF.
+**/
+VOID
+PchPsfEnableVtd (
+  VOID
+  );
+
+/**
+  Disable PSF address-based peer-to-peer decoding.
+**/
+VOID
+PchPsfDisableP2pDecoding (
+  VOID
+  );
+
+/**
+  This procedure will hide PMC device at PSF level
+**/
+VOID
+PsfHidePmcDevice (
+  VOID
+  );
+
+/**
+  This procedure will disable D3:F0 device at PSF level for PCH-LP
+**/
+VOID
+PsfDisableD3F0 (
+  VOID
+  );
+
+/**
+  This procedure will disable PSF upstream completion tracking for HDAudio on PCH-LP
+**/
+VOID
+PsfDisableUpstreamCompletionTrackingForHda (
+  VOID
+  );
+
+#endif // _PCH_PSF_PRIVATE_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Psf/LibraryPrivate/PsfLib/PeiDxeSmmPsfLibVer2.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Psf/LibraryPrivate/PsfLib/PeiDxeSmmPsfLibVer2.inf
new file mode 100644
index 0000000000..d8fc52444a
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Psf/LibraryPrivate/PsfLib/PeiDxeSmmPsfLibVer2.inf
@@ -0,0 +1,40 @@
+## @file
+#  PEI/DXE/SMM PCH PSF Private Lib for TigerLake PCH
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION                    = 0x00010017
+BASE_NAME                      = PeiDxeSmmPsfLibTgl
+FILE_GUID                      = 28B03D2C-6FD5-4061-96B8-39E3F0402DE5
+VERSION_STRING                 = 1.0
+MODULE_TYPE                    = BASE
+LIBRARY_CLASS                  = PsfLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[LibraryClasses]
+  BaseLib
+  IoLib
+  DebugLib
+  PciSegmentLib
+  PchInfoLib
+  PchPcrLib
+  SataLib
+  CpuPcieInfoFruLib
+  PchPciBdfLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+  PsfLib.c
+  PsfLibVer2.c
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Psf/LibraryPrivate/PsfLib/PsfLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Psf/LibraryPrivate/PsfLib/PsfLib.c
new file mode 100644
index 0000000000..1f0b11c11a
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Psf/LibraryPrivate/PsfLib/PsfLib.c
@@ -0,0 +1,203 @@
+/** @file
+  This file contains PSF routines for RC usage
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/SataLib.h>
+#include <Library/CpuPcieInfoFruLib.h>
+#include <Library/PsfLib.h>
+#include <PchLimits.h>
+#include <Register/PchRegsPsf.h>
+#include <PchPcieRpInfo.h>
+#include "PsfLibInternal.h"
+#include <Library/PchPciBdfLib.h>
+
+/**
+  Get PSF SideBand Port ID from PSF ID (1 - PSF1, 2 - PSF2, ...)
+
+  @param[in] PsfId             PSF ID (1 - PSF1, 2 - PSF2, ...)
+
+  @retval PSF SideBand Port ID
+**/
+PCH_SBI_PID
+PsfSbPortId (
+  UINT32        PsfId
+  )
+{
+  UINT32          PsfTableIndex;
+  PSF_SEGMENT     *PsfTable;
+  UINT32          PsfTableSize;
+
+  PsfSegments (&PsfTable, &PsfTableSize);
+
+  for (PsfTableIndex = 0; PsfTableIndex < PsfTableSize; PsfTableIndex++) {
+    if (PsfTable[PsfTableIndex].Id == PsfId) {
+      return PsfTable[PsfTableIndex].SbPid;
+    }
+  }
+
+  ASSERT (FALSE);
+  return 0;
+}
+
+
+/**
+  Get PCH Root PSF ID. This is the PSF segment to which OPDMI/DMI is connected.
+
+  @retval PsfId             Root PSF ID
+**/
+UINT32
+PsfRootId (
+  VOID
+  )
+{
+  PSF_SEGMENT     *PsfTable;
+  UINT32          PsfTableSize;
+
+  PsfSegments (&PsfTable, &PsfTableSize);
+
+  return PsfTable[0].Id;
+}
+
+/**
+  Add EOI Target in a given PSF
+
+  @param[in] PsfId             PSF ID (1 - PSF1, 2 - PSF2, ...)
+  @param[in] TargetId          EOI Target ID
+**/
+STATIC
+VOID
+PsfAddEoiTarget (
+  UINT32           PsfId,
+  PSF_PORT_DEST_ID TargetId
+  )
+{
+  UINT16      EoiTargetBase;
+  UINT16      EoiControlBase;
+  UINT8       NumOfEnabledTargets;
+  UINT8       MaximalNumberOfTargets;
+  PCH_SBI_PID PsfSbiPortId;
+  UINT32      Data32;
+  UINT8       TargetIndex;
+
+  MaximalNumberOfTargets = PsfEoiRegData (PsfId, &EoiTargetBase, &EoiControlBase);
+  PsfSbiPortId = PsfSbPortId (PsfId);
+
+  //
+  // Get number of enabled agents from PSF_x_PSF_MC_CONTROL_MCAST0_RS0_EOI register
+  //
+  Data32 = PchPcrRead32 (PsfSbiPortId, EoiControlBase);
+  NumOfEnabledTargets = (UINT8) (Data32 >> N_PCH_PSFX_PCR_MC_CONTROL_MCASTX_NUMMC);
+
+  //
+  // Check if target was not already enabled
+  // Targets from a different PSF segment are aggregated into single destination on
+  // current PSF segment.
+  //
+  for (TargetIndex = 0; TargetIndex < NumOfEnabledTargets; TargetIndex++) {
+    Data32 = PchPcrRead32 (PsfSbiPortId, EoiTargetBase + TargetIndex * 4);
+    //
+    // If target already added don't add it again
+    //
+    if (Data32 == TargetId.RegVal) {
+      ASSERT (FALSE);
+      return;
+    }
+    //
+    // If target is from different PSF segment than currently being analyzed
+    // it is enough that its PsfID is matching
+    //
+    if ((Data32 & B_PCH_PSFX_PCR_TARGET_PSFID) >> N_PCH_PSFX_PCR_TARGET_PSFID == TargetId.Fields.PsfId) {
+      return;
+    }
+  }
+
+  //
+  // Check if next one can be added
+  //
+  if (NumOfEnabledTargets >= MaximalNumberOfTargets) {
+    ASSERT (FALSE);
+    return;
+  }
+
+  //
+  // Add next target
+  // Configure Multicast Destination ID register with target device on PSF.
+  // Configuration must be done in next available PSF_MC_AGENT_MCAST0_RS0_TGT<x>_EOI register
+  // so that other targets  are not overridden. <x> is known from the number of multicast agents
+  // in Multicast Control Register. Value programmed is based on
+  // PsfID, PortGroupID, PortID and ChannelID of the target
+  //
+  PchPcrWrite32 (PsfSbiPortId, EoiTargetBase + NumOfEnabledTargets * 4, TargetId.RegVal);
+
+  //
+  // Enable new target
+  // Configure PSF_x_PSF_MC_CONTROL_MCAST0_RS0_EOI, increase NumMc and set MultCEn
+  //
+  NumOfEnabledTargets++;
+  Data32 = (NumOfEnabledTargets << N_PCH_PSFX_PCR_MC_CONTROL_MCASTX_NUMMC) | B_PCH_PSFX_PCR_MC_CONTROL_MCASTX_MULTCEN;
+  PchPcrWrite32 (PsfSbiPortId, EoiControlBase, Data32);
+}
+
+/**
+  Enable EOI Target
+
+  @param[in] TargetId  Target ID
+**/
+STATIC
+VOID
+PsfEnableEoiTarget (
+  PSF_PORT_DEST_ID     TargetId
+  )
+{
+  UINT32 RootLevelPsf;
+
+  RootLevelPsf = PsfRootId ();
+
+  //
+  // Enable EOI target in root PSF
+  //
+  PsfAddEoiTarget (RootLevelPsf, TargetId);
+
+  //
+  // Enable EOI target on other PSF segment if target
+  // is not located on root PSF
+  //
+  if (TargetId.Fields.PsfId != RootLevelPsf) {
+    PsfAddEoiTarget (TargetId.Fields.PsfId, TargetId);
+  }
+}
+
+/**
+  This function enables EOI message forwarding in PSF for PCIe ports
+  for cases where IOAPIC is present behind this root port.
+
+  @param[in] RpIndex        Root port index (0 based)
+
+  @retval Status
+**/
+EFI_STATUS
+PsfConfigurEoiForPciePort (
+  IN  UINT32  RpIndex
+  )
+{
+  ASSERT (RpIndex < GetPchMaxPciePortNum ());
+
+  //
+  // If there is an IOAPIC discovered behind root port program PSF Multicast registers
+  // accordingly to CNL PCH BWG PSF EOI Multicast Configuration
+  // Since there is a device behind RootPort to which EOI needs to be forwarded
+  // enable multicast (MULTCEN) and increase the number of multicast agents (NUMMC)
+  // in Multicast Control Register.
+  //
+  PsfEnableEoiTarget (PsfPcieDestinationId (RpIndex));
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Psf/LibraryPrivate/PsfLib/PsfLibInternal.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Psf/LibraryPrivate/PsfLib/PsfLibInternal.h
new file mode 100644
index 0000000000..9d636b5298
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Psf/LibraryPrivate/PsfLib/PsfLibInternal.h
@@ -0,0 +1,470 @@
+/** @file
+  This file contains internal header for PSF lib usage
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_PSF_PRIVATE_LIB_INTERNAL_H_
+#define _PCH_PSF_PRIVATE_LIB_INTERNAL_H_
+
+#include <Library/PsfLib.h>
+#include <Register/PchPcrRegs.h>
+
+#define PSF_PORT_NULL ((PSF_PORT){0,0})
+#define PSF_IS_PORT_NULL(PsfPort) ((PsfPort.PsfPid == 0) && (PsfPort.RegBase == 0))
+
+typedef struct {
+  PCH_SBI_PID  PsfPid;
+  UINT32       RegisterAddress;
+  UINT8        Fro;
+} PSF_PORT_RELAXED_ORDERING_CONFIG_REG;
+/**
+  Disable bridge (e.g. PCIe Root Port) at PSF level
+
+  @param[in] PsfPort  PSF PORT data structure
+**/
+VOID
+PsfDisableBridge (
+  IN PSF_PORT  PsfPort
+  );
+
+/**
+  Disable bridge (e.g. PCIe Root Port) at PSF level in RS3
+
+  @param[in] PsfPort  PSF PORT data structure
+**/
+VOID
+PsfRs3DisableBridge (
+  IN PSF_PORT  PsfPort
+  );
+
+/**
+  Check if bridge (e.g. PCIe Root Port) is enabled at PSF level
+
+  @param[in] PsfPort  PSF PORT data structure
+
+  @retval TRUE        Bridge behind PSF Port is enabled
+          FALSE       Bridge behind PSF Port is disabled
+**/
+BOOLEAN
+PsfIsBridgeEnabled (
+  IN PSF_PORT  PsfPort
+  );
+
+/**
+  Disable device IOSpace at PSF level
+  Method not for bridges (e.g. PCIe Root Port)
+
+  @param[in] PsfPort     PSF PORT data structure
+**/
+VOID
+PsfDisableDeviceIoSpace (
+  IN PSF_PORT  PsfPort
+  );
+
+/**
+  Enable device IOSpace at PSF level
+  Method not for bridges (e.g. PCIe Root Port)
+
+  @param[in] PsfPort     PSF PORT data structure
+**/
+VOID
+PsfEnableDeviceIoSpace (
+  IN PSF_PORT  PsfPort
+  );
+
+/**
+  Disable device Memory Space at PSF level
+  Method not for bridges (e.g. PCIe Root Port)
+
+  @param[in] PsfPort     PSF PORT data structure
+**/
+VOID
+PsfDisableDeviceMemSpace (
+  IN PSF_PORT  PsfPort
+  );
+
+/**
+  Enable device Memory Space at PSF level
+  Method not for bridges (e.g. PCIe Root Port)
+
+  @param[in] PsfPort     PSF PORT data structure
+**/
+VOID
+PsfEnableDeviceMemSpace (
+  IN PSF_PORT  PsfPort
+  );
+
+/**
+  Set device BARx address at PSF level
+  Method not for bridges (e.g. PCIe Root Port)
+
+  @param[in] PsfPort     PSF PORT data structure
+  @param[in] BarNum      BAR Number (0:BAR0, 1:BAR1, ...)
+  @param[in] BarValue    32bit BAR value
+**/
+VOID
+PsfSetDeviceBarValue (
+  IN PSF_PORT  PsfPort,
+  IN UINT8     BarNum,
+  IN UINT32    BarValue
+  );
+
+/**
+  Return PSF_PORT for TraceHub device
+
+  @retval    PsfPort         PSF PORT structure for TraceHub device
+**/
+PSF_PORT
+PsfTraceHubPort (
+  VOID
+  );
+
+/**
+  This procedure will return PSF_PORT for TraceHub ACPI device
+
+  @retval    PsfPort         PSF PORT structure for TraceHub ACPI device
+**/
+PSF_PORT
+PsfTraceHubAcpiDevPort (
+  VOID
+  );
+
+/**
+  This procedure will return PSF_PORT for SOL device
+
+  @retval    PsfPort         PSF PORT structure for SOL device
+**/
+PSF_PORT
+PsfSolPort (
+  VOID
+  );
+
+/**
+  Return PSF_PORT for ISH device
+
+  @retval    PsfPort         PSF PORT structure for ISH device
+**/
+PSF_PORT
+PsfIshPort (
+  VOID
+  );
+
+/**
+  Return PSF_PORT for FPAK device
+
+  @retval    PsfPort         PSF PORT structure for FPAK device
+**/
+PSF_PORT
+PsfFpakPort (
+  VOID
+  );
+
+/**
+  Return PSF_PORT for CNVi device
+
+  @retval    PsfPort         PSF PORT structure for CNVi device
+**/
+PSF_PORT
+PsfCnviPort (
+  VOID
+  );
+
+/**
+  Return PSF_PORT for PMC device
+
+  @retval    PsfPort         PSF PORT structure for PMC device
+**/
+PSF_PORT
+PsfPmcPort (
+  VOID
+  );
+
+/**
+  Return second level PSF_PORT to which PCIE Root Port device is connected (directly)
+
+  @param[in] RpIndex        PCIe Root Port Index (0 based)
+
+  @retval    PsfPort        PSF PORT structure for PCIe
+**/
+PSF_PORT
+PsfPcieSecondLevelPort (
+  IN UINT32  RpIndex
+  );
+
+/**
+  Return PSF_PORT at root PSF level to which PCIe Root Port device is connected
+
+  @param[in] RpIndex        PCIe Root Port Index (0 based)
+
+  @retval    PsfPort        PSF PORT structure for PCIe
+
+**/
+PSF_PORT
+PsfRootPciePort (
+  IN UINT32  RpIndex
+  );
+
+/**
+  Return RS3 PSF_PORT at root PSF level to which PCIe Root Port device is connected
+
+  @param[in] RpIndex        PCIe Root Port Index (0 based)
+
+  @retval    PsfPort        PSF PORT structure for PCIe
+**/
+PSF_PORT
+PsfRootRs3PciePort (
+  IN UINT32  RpIndex
+  );
+
+/**
+  Check if PCIe Root Port is enabled
+
+  @param[in] RpIndex        PCIe Root Port Index (0 based)
+
+  @retval TRUE              PCIe Root Port is enabled
+          FALSE             PCIe Root Port is disabled
+**/
+BOOLEAN
+PsfIsPcieRootPortEnabled (
+  IN UINT32  RpIndex
+  );
+
+//
+// Type of enpoint connected to PSF port.
+// PsfNullPort is used for ports which do not exist
+//
+typedef enum {
+  PsfNullPort,
+  PsfToPsfPort,
+  PsfPcieCtrlPort
+} PSF_TOPO_PORT_TYPE;
+
+//
+// Structure for storing information on location in PSF topology
+// Every PSF node is identified by PsfID and PsfPortId
+//
+typedef struct {
+  UINT8         PsfId;
+  UINT8         PortId;
+} PSF_TOPO_PORT;
+
+#define PSF_TOPO_PORT_NULL ((PSF_TOPO_PORT){0, 0})
+#define PSF_IS_TOPO_PORT_NULL(PsfTopoPort) (((PsfTopoPort).PsfId == 0) && ((PsfTopoPort).PortId == 0))
+
+//
+// This is optional field containing PSF port specific data
+//
+typedef union {
+  UINT32  PcieCtrlIndex;
+} PSF_TOPO_PORT_DATA;
+
+//
+// Structure representing PSF port in PSF topology
+// If port is of PsfToPsfPort type Child will point to the first
+// port of sub PSF segment.
+//
+typedef struct PSF_TOPOLOGY {
+  PSF_TOPO_PORT              PsfPort;
+  PSF_TOPO_PORT_TYPE         PortType;
+  CONST struct PSF_TOPOLOGY  *Child;
+  PSF_TOPO_PORT_DATA         PortData;
+} PSF_TOPOLOGY;
+
+//
+// Tag for identifying last element of PSF_TOPOLOGY type array
+//
+#define PSF_TOPOLOGY_END   {{0, 0}, PsfNullPort, NULL}
+
+/**
+  Get PSF Pcie Tree topology
+
+  @param[in] PsfTopology          PSF Port from PSF PCIe tree topology
+
+  @retval PsfTopology             PSF PCIe tree topology
+**/
+CONST PSF_TOPOLOGY*
+PsfGetRootPciePsfTopology (
+  VOID
+  );
+
+//
+// Structure for storing data on PCIe controller to PSF assignment and GrantCount register offsets
+//
+typedef struct {
+  PCH_SBI_PID  PsfPid;
+  UINT16       DevGntCnt0Base;
+  UINT16       TargetGntCntPg1Tgt0Base;
+} PSF_GRANT_COUNT_REG;
+
+/**
+  Grant count regs data for PSF that is directly connected to PCIe Root Ports
+
+  @param[in]  Controller     PCIe Root Port Controller index (0 based)
+  @param[out] GrantCountReg  Structure with PSF Grant Count register data
+**/
+VOID
+PsfPcieGrantCountBaseReg (
+  IN  UINT8                Controller,
+  OUT PSF_GRANT_COUNT_REG  *GrantCountReg
+  );
+
+/**
+  Get Grant Count number (Device Grant Count and Target Grant Count)
+  for PSF that is directly connected to PCIe Root Ports
+
+  @param[in]  Controller    PCIe Root Port Controller index
+  @param[in]  Channel       PCIe Root Port Channel index
+  @param[out] DgcrNo        Device Grant Count number
+  @param[out] PgTgtNo       Target Grant Count number
+**/
+VOID
+PsfPcieGrantCountNumber (
+  IN  UINT8 Controller,
+  IN  UINT8 Channel,
+  OUT UINT8 *DgcrNo,
+  OUT UINT8 *PgTgtNo
+  );
+
+/**
+  Grant count regs data for a given PSF-to-PSF port.
+
+  @param[in] PsfTopoPort         PSF-to-PSF port
+
+  @param[out] GrantCountReg      Structure with PSF Grant Count register data
+**/
+VOID
+PsfSegmentGrantCountBaseReg (
+  IN PSF_TOPO_PORT         PsfTopoPort,
+  OUT PSF_GRANT_COUNT_REG  *GrantCountReg
+  );
+
+/**
+  Grant Count number (Device Grant Count and Target Grant Count) for a given PSF-to-PSF port.
+
+  @param[in] PsfTopoPort         PSF-to-PSF port
+  @param[out] DgcrNo             Device Grant Count number
+  @param[out] PgTgtNo            Target Grant Count number
+**/
+VOID
+PsfSegmentGrantCountNumber (
+  IN PSF_TOPO_PORT PsfTopoPort,
+  OUT UINT8        *DgcrNo,
+  OUT UINT8        *PgTgtNo
+  );
+
+//
+// Do not override PSF Grant Count value and leave HW default setting
+//
+#define DEFAULT_PCIE_GRANT_COUNT 0xFF
+
+/**
+  Get PSF SideBand Port ID from PSF ID (1 - PSF1, 2 - PSF2, ...)
+
+  @param[in] PsfId             PSF ID (1 - PSF1, 2 - PSF2, ...)
+
+  @retval PSF SideBand Port ID
+**/
+PCH_SBI_PID
+PsfSbPortId (
+  UINT32        PsfId
+  );
+
+/**
+  Get EOI register data for given PSF ID
+
+  @param[in]  PsfId           PSF ID (1 - PSF1, 2 - PSF2, ...)
+  @param[out] EoiTargetBase   EOI Target register
+  @param[out] EoiControlBase  EOI Control register
+
+  @retval MaxTargets          Number of supported targets
+
+**/
+UINT8
+PsfEoiRegData (
+  UINT32        PsfId,
+  UINT16        *EoiTargetBase,
+  UINT16        *EoiControlBase
+  );
+
+/**
+  Get MCTP register data for given PSF ID
+
+  @param[in]  PsfId            PSF ID (1 - PSF1, 2 - PSF2, ...)
+  @param[out] MctpTargetBase   MCTP Target register
+  @param[out] MctpControlBase  MCTP Control register
+
+  @retval MaxTargets           Number of supported targets
+
+**/
+UINT8
+PsfMctpRegData (
+  UINT32        PsfId,
+  UINT16        *MctpTargetBase,
+  UINT16        *MctpControlBase
+  );
+
+/**
+  Check if MCTP is supported
+
+  @retval TRUE              MCTP is supported
+          FALSE             MCTP is not supported
+**/
+BOOLEAN
+PsfIsMctpSupported (
+  VOID
+  );
+
+/**
+  Return the PSF (Root level) Function Config PSF_PORT for PCIe Root Port
+
+  @param[in] RpIndex        PCIe Root Port Index (0 based)
+
+  @retval    PsfPort        PSF PORT structure for PCIe Function Config
+**/
+PSF_PORT
+PsfRootPcieFunctionConfigPort (
+  IN UINT32  RpIndex
+  );
+
+/**
+  Return the PSF (Root level) RS3 Function Config PSF_PORT for PCIe Root Port
+
+  @param[in] RpIndex        PCIe Root Port Index (0 based)
+
+  @retval    PsfPort        PSF PORT structure for PCIe Function Config
+**/
+PSF_PORT
+PsfRootRs3PcieFunctionConfigPort (
+  IN UINT32  RpIndex
+  );
+
+/**
+  Return the PSF Function Config Second Level PSF_PORT for PCIe Root Port
+
+  @param[in] RpIndex        PCIe Root Port Index (0 based)
+
+  @retval    PsfPort        PSF PORT structure for PCIe Function Config
+**/
+PSF_PORT
+PsfPcieFunctionConfigSecondLevelPort (
+  IN UINT32  RpIndex
+  );
+
+/**
+  This function returns Psf Port Relaxed Ordering Configs
+
+  @param[out] PsfPortRelaxedOrderingConfigRegs                          PCH Series specific table
+  @param[out] PsfPortRelaxedOrderingConfigRegsTableSize                 PCH Series specific table size
+  @param[out] PsfPortRelaxedOrderingConfigRegsPchTypeSpecific           PCH type specific table
+  @param[out] PsfPortRelaxedOrderingConfigRegsPchTypeSpecificTableSize  PCH type specific table size
+**/
+VOID
+GetPsfPortRelaxedOrderingTables (
+  PSF_PORT_RELAXED_ORDERING_CONFIG_REG** PsfPortRelaxedOrderingConfigRegs,
+  UINT32*                                PsfPortRelaxedOrderingConfigRegsTableSize,
+  PSF_PORT_RELAXED_ORDERING_CONFIG_REG** PsfPortRelaxedOrderingConfigRegsPchTypeSpecific,
+  UINT32*                                PsfPortRelaxedOrderingConfigRegsPchTypeSpecificTableSize
+  );
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Psf/LibraryPrivate/PsfLib/PsfLibVer2.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Psf/LibraryPrivate/PsfLib/PsfLibVer2.c
new file mode 100644
index 0000000000..fd21e5bed4
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Psf/LibraryPrivate/PsfLib/PsfLibVer2.c
@@ -0,0 +1,115 @@
+/** @file
+  This file contains internal PSF routines for PCH PSF VER2 lib usage
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/SataLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Register/PchRegsPsf.h>
+#include "PsfLibInternal.h"
+#include <PchPcieRpInfo.h>
+
+
+/**
+  Get EOI register data for given PSF ID
+
+  @param[in]  PsfId           PSF ID (1 - PSF1, 2 - PSF2, ...)
+  @param[out] EoiTargetBase   EOI Target register
+  @param[out] EoiControlBase  EOI Control register
+
+  @retval MaxTargets          Number of supported targets
+
+**/
+UINT8
+PsfEoiRegData (
+  UINT32        PsfId,
+  UINT16        *EoiTargetBase,
+  UINT16        *EoiControlBase
+  )
+{
+  UINT8  MaxTargets;
+
+  MaxTargets = 0;
+  *EoiTargetBase = 0;
+  *EoiControlBase = 0;
+
+  switch (PsfId) {
+    case 1:
+      break;
+
+    case 3:
+      break;
+
+    case 7:
+      break;
+
+    case 8:
+      break;
+
+    case 9:
+      break;
+
+    default:
+      break;
+
+  }
+  return MaxTargets;
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED PSF_PORT_DEST_ID PchLpRpDestId[] =
+{
+  {0x18000}, {0x18001}, {0x18002}, {0x18003}, // SPA: PSF1, PortID = 0
+  {0x18100}, {0x18101}, {0x18102}, {0x18103}, // SPB: PSF1, PortID = 1
+  {0x18200}, {0x18201}, {0x18202}, {0x18203}, // SPC: PSF1, PortID = 2
+};
+
+/**
+  PCIe PSF port destination ID (psf_id:port_group_id:port_id:channel_id)
+
+  @param[in] RpIndex        PCIe Root Port Index (0 based)
+
+  @retval Destination ID
+**/
+PSF_PORT_DEST_ID
+PsfPcieDestinationId (
+  IN UINT32  RpIndex
+  )
+{
+  if (RpIndex < ARRAY_SIZE (PchLpRpDestId)) {
+    return PchLpRpDestId[RpIndex];
+  }
+  ASSERT (FALSE);
+  return (PSF_PORT_DEST_ID){0};
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED PSF_SEGMENT mPchLpPsfTable[] =
+{
+  {1, PID_PSF1},
+  {2, PID_PSF2},
+  {3, PID_PSF3},
+  {4, PID_PSF4},
+  {5, PID_CSME_PSF},
+  {6, PID_PSF6}
+};
+
+/**
+  Get list of supported PSF segments.
+
+  @param[out] PsfTable        Array of supported PSF segments
+  @param[out] PsfTableLength  Length of PsfTable
+**/
+VOID
+PsfSegments (
+  OUT PSF_SEGMENT  **PsfTable,
+  OUT UINT32       *PsfTableLength
+  )
+{
+*PsfTable = mPchLpPsfTable;
+    *PsfTableLength = ARRAY_SIZE (mPchLpPsfTable);
+}
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 26/40] TigerlakeSiliconPkg/IpBlock: Add Sata component
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (23 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 25/40] TigerlakeSiliconPkg/IpBlock: Add Psf component Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 27/40] TigerlakeSiliconPkg/IpBlock: Add SerialIo component Heng Luo
                   ` (13 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * IpBlock/Sata/Library

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Sata/Library/PeiDxeSmmSataLib/PeiDxeSmmSataLibVer2.inf |  32 ++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Sata/Library/PeiDxeSmmSataLib/SataLib.c                | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Sata/Library/PeiDxeSmmSataLib/SataLibVer2.c            |  83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 253 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Sata/Library/PeiDxeSmmSataLib/PeiDxeSmmSataLibVer2.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Sata/Library/PeiDxeSmmSataLib/PeiDxeSmmSataLibVer2.inf
new file mode 100644
index 0000000000..1c304fed59
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Sata/Library/PeiDxeSmmSataLib/PeiDxeSmmSataLibVer2.inf
@@ -0,0 +1,32 @@
+## @file
+# PEI/DXE/SMM PCH SATA library Ver2
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPchSataLibVer2
+FILE_GUID = 2519ADE8-D971-4551-8A8E-2EB55DFC555B
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = SataLib
+
+[LibraryClasses]
+BaseLib
+PciSegmentLib
+PchInfoLib
+PchPciBdfLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Sources]
+SataLib.c
+SataLibVer2.c
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Sata/Library/PeiDxeSmmSataLib/SataLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Sata/Library/PeiDxeSmmSataLib/SataLib.c
new file mode 100644
index 0000000000..49cba49910
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Sata/Library/PeiDxeSmmSataLib/SataLib.c
@@ -0,0 +1,138 @@
+/** @file
+  Pch SATA library.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/SataLib.h>
+#include <Register/PchRegs.h>
+#include <Register/SataRegs.h>
+#include <Library/PchPciBdfLib.h>
+
+/**
+  Get SATA controller address that can be passed to the PCI Segment Library functions.
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval SATA controller address in PCI Segment Library representation
+**/
+UINT64
+SataRegBase (
+  IN UINT32      SataCtrlIndex
+  )
+{
+  ASSERT (SataCtrlIndex < MaxSataControllerNum ());
+
+  return SataPciCfgBase (SataCtrlIndex);
+}
+
+/**
+  Get SATA controller's Port Present Status
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval     Port Present Status
+**/
+UINT8
+GetSataPortPresentStatus (
+  IN UINT32  SataCtrlIndex
+  )
+{
+  ASSERT (SataCtrlIndex < MaxSataControllerNum ());
+
+  return PciSegmentRead8 (SataPciCfgBase (SataCtrlIndex) + R_SATA_CFG_PCS + 2);
+}
+
+/**
+  Get SATA controller Function Disable Status
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval 0 SATA Controller is not Function Disabled
+  @retval 1 SATA Controller is Function Disabled
+**/
+BOOLEAN
+SataControllerFunctionDisableStatus (
+  IN UINT32  SataCtrlIndex
+  )
+{
+  UINT32 SataGc;
+  ASSERT (SataCtrlIndex < MaxSataControllerNum ());
+  SataGc = PciSegmentRead32 (SataPciCfgBase (SataCtrlIndex) + R_SATA_CFG_SATAGC);
+  return !!(SataGc & BIT10);
+}
+
+/**
+  Get SATA controller ABAR size
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval SATA controller ABAR size
+**/
+UINT32
+GetSataAbarSize (
+  IN UINT32  SataCtrlIndex
+  )
+{
+  UINT32 SataGc;
+  ASSERT (SataCtrlIndex < MaxSataControllerNum ());
+  SataGc = PciSegmentRead32 (SataPciCfgBase (SataCtrlIndex) + R_SATA_CFG_SATAGC);
+
+  switch (SataGc & B_SATA_CFG_SATAGC_ASSEL) {
+    case V_SATA_CFG_SATAGC_ASSEL_2K:
+      return SIZE_2KB;
+      break;
+
+    case V_SATA_CFG_SATAGC_ASSEL_16K:
+      return SIZE_16KB;
+      break;
+
+    case V_SATA_CFG_SATAGC_ASSEL_32K:
+      return SIZE_32KB;
+      break;
+
+    case V_SATA_CFG_SATAGC_ASSEL_64K:
+      return SIZE_64KB;
+      break;
+
+    case V_SATA_CFG_SATAGC_ASSEL_128K:
+      return SIZE_128KB;
+      break;
+
+    case V_SATA_CFG_SATAGC_ASSEL_512K:
+      return SIZE_256KB;
+      break;
+
+    default:
+      return SIZE_2KB;
+      break;
+  }
+}
+
+/**
+  Get SATA controller AHCI base address
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval SATA controller AHCI base address
+**/
+UINT32
+GetSataAhciBase (
+  IN UINT32  SataCtrlIndex
+  )
+{
+  ASSERT (SataCtrlIndex < MaxSataControllerNum ());
+
+  return PciSegmentRead32 (SataPciCfgBase (SataCtrlIndex) + R_SATA_CFG_AHCI_BAR) & 0xFFFFF800;
+}
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Sata/Library/PeiDxeSmmSataLib/SataLibVer2.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Sata/Library/PeiDxeSmmSataLib/SataLibVer2.c
new file mode 100644
index 0000000000..cde74e4e76
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Sata/Library/PeiDxeSmmSataLib/SataLibVer2.c
@@ -0,0 +1,83 @@
+/** @file
+  Pch SATA library.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/DebugLib.h>
+#include <Library/PchInfoLib.h>
+#include <PchLimits.h>
+#include <Register/SataRegs.h>
+#include <Library/SataLib.h>
+
+/**
+  Get Maximum Sata Controller Number
+
+  @retval Maximum Sata Controller Number
+**/
+UINT8
+MaxSataControllerNum (
+  VOID
+  )
+{
+  return 1;
+}
+
+/**
+  Get Maximum Sata Port Number
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval     Maximum Sata Port Number
+**/
+UINT8
+MaxSataPortNum (
+  IN UINT32      SataCtrlIndex
+  )
+{
+  ASSERT (SataCtrlIndex < MaxSataControllerNum ());
+
+  return 2;
+}
+
+/**
+  Check if SATA controller supports RST remapping
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval     TRUE                Controller supports remapping
+  @retval     FALSE               Controller does not support remapping
+
+**/
+BOOLEAN
+IsRemappingSupportedOnSata (
+  IN UINT32  SataCtrlIndex
+  )
+{
+  ASSERT (SataCtrlIndex < MaxSataControllerNum ());
+
+  return FALSE;
+}
+
+/**
+  Checks if SoC supports the SATA PGD power down on given
+  SATA controller.
+
+  @param[in] SataCtrlIndex  SATA controller index
+
+  @retval TRUE   SATA PGD power down supported
+  @retval FALSE  SATA PGD power down not supported
+**/
+BOOLEAN
+IsSataPowerGatingSupported (
+  IN UINT32 SataCtrlIndex
+  )
+{
+  return TRUE;
+}
+
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 27/40] TigerlakeSiliconPkg/IpBlock: Add SerialIo component
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (24 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 26/40] TigerlakeSiliconPkg/IpBlock: Add Sata component Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 28/40] TigerlakeSiliconPkg/IpBlock: Add Smbus component Heng Luo
                   ` (12 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

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.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Heng Luo <heng.luo@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


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 28/40] TigerlakeSiliconPkg/IpBlock: Add Smbus component
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (25 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 27/40] TigerlakeSiliconPkg/IpBlock: Add SerialIo component Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 29/40] TigerlakeSiliconPkg/IpBlock: Add Spi component Heng Luo
                   ` (11 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * IpBlock/Smbus/IncludePrivate

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Smbus/IncludePrivate/Register/SmbusRegs.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Smbus/IncludePrivate/Register/SmbusRegs.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Smbus/IncludePrivate/Register/SmbusRegs.h
new file mode 100644
index 0000000000..c863615583
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Smbus/IncludePrivate/Register/SmbusRegs.h
@@ -0,0 +1,50 @@
+/** @file
+  Register names for PCH Smbus Device.
+
+  Conventions:
+
+  - Register definition format:
+    Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpace_RegisterName
+  - Prefix:
+    Definitions beginning with "R_" are registers
+    Definitions beginning with "B_" are bits within registers
+    Definitions beginning with "V_" are meaningful values within the bits
+    Definitions beginning with "S_" are register size
+    Definitions beginning with "N_" are the bit position
+  - [GenerationName]:
+    Three letter acronym of the generation is used (e.g. SKL,KBL,CNL etc.).
+    Register name without GenerationName applies to all generations.
+  - [ComponentName]:
+    This field indicates the component name that the register belongs to (e.g. PCH, SA etc.)
+    Register name without ComponentName applies to all components.
+    Register that is specific to -LP denoted by "_PCH_LP_" in component name.
+  - SubsystemName:
+    This field indicates the subsystem name of the component that the register belongs to
+    (e.g. PCIE, USB, SATA, GPIO, PMC etc.).
+  - RegisterSpace:
+    MEM - MMIO space register of subsystem.
+    IO  - IO space register of subsystem.
+    PCR - Private configuration register of subsystem.
+    CFG - PCI configuration space register of subsystem.
+  - RegisterName:
+    Full register name.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_REGS_SMBUS_H_
+#define _PCH_REGS_SMBUS_H_
+
+//
+// SMBus Controller Registers
+//
+#define R_SMBUS_CFG_BASE                      0x20
+#define B_SMBUS_CFG_BASE_BAR                  0x0000FFE0
+
+//
+// SMBus I/O Registers
+//
+#define R_SMBUS_IO_HSTS                  0x00  ///< Host Status Register R/W
+#define B_SMBUS_IO_SMBALERT_STS          0x20
+
+#endif
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 29/40] TigerlakeSiliconPkg/IpBlock: Add Spi component
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (26 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 28/40] TigerlakeSiliconPkg/IpBlock: Add Smbus component Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 30/40] TigerlakeSiliconPkg/IpBlock: Add Vtd component Heng Luo
                   ` (10 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * IpBlock/Spi/IncludePrivate
  * IpBlock/Spi/Library
  * IpBlock/Spi/LibraryPrivate
  * IpBlock/Spi/Smm

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/IncludePrivate/Library/SpiAccessPrivateLib.h                                 |   40 ++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/IncludePrivate/Library/SpiCommonLib.h                                        |  364 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/IncludePrivate/Register/SpiRegs.h                                            |  136 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Library/PeiDxeSmmSpiAccessLib/PeiDxeSmmSpiAccessLib.inf                      |   33 ++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Library/PeiDxeSmmSpiAccessLib/SpiAccessLib.c                                 |  477 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/BaseSpiCommonLib/BaseSpiCommonLib.inf                         |   31 +++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/BaseSpiCommonLib/SpiCommon.c                                  | 1115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/PeiDxeSmmSpiAccessPrivateLib/PeiDxeSmmSpiAccessPrivateLib.inf |   40 ++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/PeiDxeSmmSpiAccessPrivateLib/SpiAccessPrivateLib.c            |  133 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Smm/Spi.c                                                                    |  296 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Smm/SpiSmm.inf                                                               |   47 +++++++++++++++++++++++++++++++++++++
 11 files changed, 2712 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/IncludePrivate/Library/SpiAccessPrivateLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/IncludePrivate/Library/SpiAccessPrivateLib.h
new file mode 100644
index 0000000000..6da88a9047
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/IncludePrivate/Library/SpiAccessPrivateLib.h
@@ -0,0 +1,40 @@
+/** @file
+  SPI library header for abstraction of SPI HW registers accesses
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SPI_ACCESS_PRIVATE_LIB_H_
+#define _SPI_ACCESS_PRIVATE_LIB_H_
+
+/**
+  Disable EISS (Enable InSMM.STS)
+**/
+VOID
+SpiDisableEiss (
+  VOID
+  );
+
+/**
+  Configure BiosLockEnable bit and BiosInterfaceLock bit according to policy setting.
+
+  @param[in] BiosLockEnable     Policy for BiosLockEnable bit programming
+  @param[in] BiosInterfaceLock  Policy for BiosInterfaceLock bit programming
+
+**/
+VOID
+SpiBiosLockEnableAndBiosInterfaceLockWithS3BootScript (
+  IN BOOLEAN  BiosLockEnable,
+  IN BOOLEAN  BiosInterfaceLock
+  );
+
+/**
+  Clears BIOS Write Protect Disable bit
+**/
+VOID
+SpiClearBiosWriteProtectDisable (
+  VOID
+  );
+
+#endif // _SPI_ACCESS_PRIVATE_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/IncludePrivate/Library/SpiCommonLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/IncludePrivate/Library/SpiCommonLib.h
new file mode 100644
index 0000000000..3290f77122
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/IncludePrivate/Library/SpiCommonLib.h
@@ -0,0 +1,364 @@
+/** @file
+  Header file for the PCH SPI Common Driver.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SPI_COMMON_LIB_H_
+#define _SPI_COMMON_LIB_H_
+
+#include <Protocol/Spi.h>
+
+//
+// Maximum time allowed while waiting the SPI cycle to complete
+//  Wait Time = 6 seconds = 6000000 microseconds
+//  Wait Period = 10 microseconds
+//
+#define SPI_WAIT_TIME   6000000     ///< Wait Time = 6 seconds = 6000000 microseconds
+#define SPI_WAIT_PERIOD 10          ///< Wait Period = 10 microseconds
+
+///
+/// Flash cycle Type
+///
+typedef enum {
+  FlashCycleRead,
+  FlashCycleWrite,
+  FlashCycleErase,
+  FlashCycleReadSfdp,
+  FlashCycleReadJedecId,
+  FlashCycleWriteStatus,
+  FlashCycleReadStatus,
+  FlashCycleMax
+} FLASH_CYCLE_TYPE;
+
+///
+/// Flash Component Number
+///
+typedef enum {
+  FlashComponent0,
+  FlashComponent1,
+  FlashComponentMax
+} FLASH_COMPONENT_NUM;
+
+///
+/// Private data structure definitions for the driver
+///
+#define PCH_SPI_PRIVATE_DATA_SIGNATURE  SIGNATURE_32 ('P', 'S', 'P', 'I')
+
+typedef struct {
+  UINT32                Signature;
+  EFI_HANDLE            Handle;
+  PCH_SPI_PROTOCOL      SpiProtocol;
+  UINT16                PchAcpiBase;
+  UINT64                PchSpiBase;
+  UINT8                 ReadPermission;
+  UINT8                 WritePermission;
+  UINT32                SfdpVscc0Value;
+  UINT32                SfdpVscc1Value;
+  UINT16                PchStrapBaseAddr;
+  UINT16                PchStrapSize;
+  UINT16                CpuStrapBaseAddr;
+  UINT16                CpuStrapSize;
+  UINT8                 NumberOfComponents;
+  UINT32                Component1StartAddr;
+  UINT32                TotalFlashSize;
+} SPI_INSTANCE;
+
+#define SPI_INSTANCE_FROM_SPIPROTOCOL(a)  CR (a, SPI_INSTANCE, SpiProtocol, PCH_SPI_PRIVATE_DATA_SIGNATURE)
+
+//
+// Function prototypes used by the SPI protocol.
+//
+
+/**
+  Initialize an SPI protocol instance.
+
+  @param[in] SpiInstance          Pointer to SpiInstance to initialize
+
+  @retval EFI_SUCCESS             The protocol instance was properly initialized
+  @exception EFI_UNSUPPORTED      The PCH is not supported by this module
+**/
+EFI_STATUS
+SpiProtocolConstructor (
+  IN     SPI_INSTANCE       *SpiInstance
+  );
+
+/**
+  This function is a hook for Spi to disable BIOS Write Protect
+
+  @retval EFI_SUCCESS             The protocol instance was properly initialized
+  @retval EFI_ACCESS_DENIED       The BIOS Region can only be updated in SMM phase
+
+**/
+EFI_STATUS
+EFIAPI
+DisableBiosWriteProtect (
+  VOID
+  );
+
+/**
+  This function is a hook for Spi to enable BIOS Write Protect
+
+
+**/
+VOID
+EFIAPI
+EnableBiosWriteProtect (
+  VOID
+  );
+
+/**
+  Acquire pch spi mmio address.
+
+  @param[in] SpiInstance          Pointer to SpiInstance to initialize
+
+  @retval PchSpiBar0              return SPI MMIO address
+**/
+UINTN
+AcquireSpiBar0 (
+  IN  SPI_INSTANCE                *SpiInstance
+  );
+
+/**
+  Release pch spi mmio address.
+
+  @param[in] SpiInstance          Pointer to SpiInstance to initialize
+
+  @retval None
+**/
+VOID
+ReleaseSpiBar0 (
+  IN  SPI_INSTANCE                *SpiInstance
+  );
+
+/**
+  Check if it's granted to do flash write.
+
+  @retval TRUE    It's secure to do flash write.
+  @retval FALSE   It's not secure to do flash write.
+**/
+BOOLEAN
+IsSpiFlashWriteGranted (
+  VOID
+  );
+
+/**
+  Read data from the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] FlashRegionType      The Flash Region type for flash cycle which is listed in the Descriptor.
+  @param[in] Address              The Flash Linear Address must fall within a region for which BIOS has access permissions.
+  @param[in] ByteCount            Number of bytes in the data portion of the SPI cycle.
+  @param[out] Buffer              The Pointer to caller-allocated buffer containing the dada received.
+                                  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashRead (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     FLASH_REGION_TYPE  FlashRegionType,
+  IN     UINT32             Address,
+  IN     UINT32             ByteCount,
+  OUT    UINT8              *Buffer
+  );
+
+/**
+  Write data to the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] FlashRegionType      The Flash Region type for flash cycle which is listed in the Descriptor.
+  @param[in] Address              The Flash Linear Address must fall within a region for which BIOS has access permissions.
+  @param[in] ByteCount            Number of bytes in the data portion of the SPI cycle.
+  @param[in] Buffer               Pointer to caller-allocated buffer containing the data sent during the SPI cycle.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashWrite (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     FLASH_REGION_TYPE  FlashRegionType,
+  IN     UINT32             Address,
+  IN     UINT32             ByteCount,
+  IN     UINT8              *Buffer
+  );
+
+/**
+  Erase some area on the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] FlashRegionType      The Flash Region type for flash cycle which is listed in the Descriptor.
+  @param[in] Address              The Flash Linear Address must fall within a region for which BIOS has access permissions.
+  @param[in] ByteCount            Number of bytes in the data portion of the SPI cycle.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashErase (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     FLASH_REGION_TYPE  FlashRegionType,
+  IN     UINT32             Address,
+  IN     UINT32             ByteCount
+  );
+
+/**
+  Read SFDP data from the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] ComponentNumber      The Componen Number for chip select
+  @param[in] Address              The starting byte address for SFDP data read.
+  @param[in] ByteCount            Number of bytes in SFDP data portion of the SPI cycle
+  @param[out] SfdpData            The Pointer to caller-allocated buffer containing the SFDP data received
+                                  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashReadSfdp (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT8              ComponentNumber,
+  IN     UINT32             Address,
+  IN     UINT32             ByteCount,
+  OUT    UINT8              *SfdpData
+  );
+
+/**
+  Read Jedec Id from the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] ComponentNumber      The Componen Number for chip select
+  @param[in] ByteCount            Number of bytes in JedecId data portion of the SPI cycle, the data size is 3 typically
+  @param[out] JedecId             The Pointer to caller-allocated buffer containing JEDEC ID received
+                                  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashReadJedecId (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT8              ComponentNumber,
+  IN     UINT32             ByteCount,
+  OUT    UINT8              *JedecId
+  );
+
+/**
+  Write the status register in the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] ByteCount            Number of bytes in Status data portion of the SPI cycle, the data size is 1 typically
+  @param[in] StatusValue          The Pointer to caller-allocated buffer containing the value of Status register writing
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashWriteStatus (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT32             ByteCount,
+  IN     UINT8              *StatusValue
+  );
+
+/**
+  Read status register in the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] ByteCount            Number of bytes in Status data portion of the SPI cycle, the data size is 1 typically
+  @param[out] StatusValue         The Pointer to caller-allocated buffer containing the value of Status register received.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashReadStatus (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT32             ByteCount,
+  OUT    UINT8              *StatusValue
+  );
+
+/**
+  Get the SPI region base and size, based on the enum type
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] FlashRegionType      The Flash Region type for for the base address which is listed in the Descriptor.
+  @param[out] BaseAddress         The Flash Linear Address for the Region 'n' Base
+  @param[out] RegionSize          The size for the Region 'n'
+
+  @retval EFI_SUCCESS             Read success
+  @retval EFI_INVALID_PARAMETER   Invalid region type given
+  @retval EFI_DEVICE_ERROR        The region is not used
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolGetRegionAddress (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     FLASH_REGION_TYPE  FlashRegionType,
+  OUT    UINT32             *BaseAddress,
+  OUT    UINT32             *RegionSize
+  );
+
+/**
+  Read PCH Soft Strap Values
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] SoftStrapAddr        PCH Soft Strap address offset from FPSBA.
+  @param[in] ByteCount            Number of bytes in SoftStrap data portion of the SPI cycle
+  @param[out] SoftStrapValue      The Pointer to caller-allocated buffer containing PCH Soft Strap Value.
+                                  If the value of ByteCount is 0, the data type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Soft Strap Length
+                                  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolReadPchSoftStrap (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT32             SoftStrapAddr,
+  IN     UINT32             ByteCount,
+  OUT    VOID               *SoftStrapValue
+  );
+
+/**
+  Read CPU Soft Strap Values
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] SoftStrapAddr        CPU Soft Strap address offset from FCPUSBA.
+  @param[in] ByteCount            Number of bytes in SoftStrap data portion of the SPI cycle.
+  @param[out] SoftStrapValue      The Pointer to caller-allocated buffer containing CPU Soft Strap Value.
+                                  If the value of ByteCount is 0, the data type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Soft Strap Length
+                                  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolReadCpuSoftStrap (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT32             SoftStrapAddr,
+  IN     UINT32             ByteCount,
+  OUT    VOID               *SoftStrapValue
+  );
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/IncludePrivate/Register/SpiRegs.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/IncludePrivate/Register/SpiRegs.h
new file mode 100644
index 0000000000..8e2029500c
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/IncludePrivate/Register/SpiRegs.h
@@ -0,0 +1,136 @@
+/** @file
+  Register names for PCH SPI device.
+
+  Conventions:
+
+  - Register definition format:
+    Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpace_RegisterName
+  - Prefix:
+    Definitions beginning with "R_" are registers
+    Definitions beginning with "B_" are bits within registers
+    Definitions beginning with "V_" are meaningful values within the bits
+    Definitions beginning with "S_" are register size
+    Definitions beginning with "N_" are the bit position
+  - [GenerationName]:
+    Three letter acronym of the generation is used (e.g. SKL,KBL,CNL etc.).
+    Register name without GenerationName applies to all generations.
+  - [ComponentName]:
+    This field indicates the component name that the register belongs to (e.g. PCH, SA etc.)
+    Register name without ComponentName applies to all components.
+    Register that is specific to -LP denoted by "_PCH_LP_" in component name.
+  - SubsystemName:
+    This field indicates the subsystem name of the component that the register belongs to
+    (e.g. PCIE, USB, SATA, GPIO, PMC etc.).
+  - RegisterSpace:
+    MEM - MMIO space register of subsystem.
+    IO  - IO space register of subsystem.
+    PCR - Private configuration register of subsystem.
+    CFG - PCI configuration space register of subsystem.
+  - RegisterName:
+    Full register name.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SPI_REGS_H_
+#define _SPI_REGS_H_
+
+//
+// SPI Registers
+//
+#define R_SPI_CFG_BAR0                      0x10
+#define B_SPI_CFG_BAR0_MASK                 0x0FFF
+
+#define R_SPI_CFG_BDE                       0xD8
+
+#define R_SPI_CFG_BC                        0xDC
+#define S_SPI_CFG_BC                        4
+#define N_SPI_CFG_BC_ASE_BWP                11
+#define B_SPI_CFG_BC_ASE_BWP                BIT11
+#define N_SPI_CFG_BC_ASYNC_SS               10
+#define B_SPI_CFG_BC_ASYNC_SS               BIT10
+#define N_SPI_CFG_BC_SYNC_SS                8
+#define B_SPI_CFG_BC_SYNC_SS                BIT8
+#define B_SPI_CFG_BC_BILD                   BIT7
+#define B_SPI_CFG_BC_BBS                    BIT6            ///< Boot BIOS strap
+#define N_SPI_CFG_BC_BBS                    6
+#define V_SPI_CFG_BC_BBS_SPI                0               ///< Boot BIOS strapped to SPI
+#define B_SPI_CFG_BC_EISS                   BIT5            ///< Enable InSMM.STS
+#define B_SPI_CFG_BC_TSS                    BIT4
+#define B_SPI_CFG_BC_SRC                    (BIT3 | BIT2)
+#define N_SPI_CFG_BC_SRC                    2
+#define V_SPI_CFG_BC_SRC_PREF_DIS_CACHE_DIS 0x01            ///< No prefetching and no caching
+#define B_SPI_CFG_BC_LE                     BIT1            ///< Lock Enable
+#define N_SPI_CFG_BC_BLE                    1
+#define B_SPI_CFG_BC_WPD                    BIT0            ///< Write Protect Disable
+
+//
+// BIOS Flash Program Registers (based on SPI_BAR0)
+//
+#define R_SPI_MEM_HSFSC                     0x04                          ///< Hardware Sequencing Flash Status and Control Register(32bits)
+#define B_SPI_MEM_HSFSC_FDBC_MASK           0x3F000000                    ///< Flash Data Byte Count ( <= 64), Count = (Value in this field) + 1.
+#define N_SPI_MEM_HSFSC_FDBC                24
+#define B_SPI_MEM_HSFSC_CYCLE_MASK          0x001E0000                    ///< Flash Cycle.
+#define N_SPI_MEM_HSFSC_CYCLE               17
+#define V_SPI_MEM_HSFSC_CYCLE_READ          0                             ///< Flash Cycle Read
+#define V_SPI_MEM_HSFSC_CYCLE_WRITE         2                             ///< Flash Cycle Write
+#define V_SPI_MEM_HSFSC_CYCLE_4K_ERASE      3                             ///< Flash Cycle 4K Block Erase
+#define V_SPI_MEM_HSFSC_CYCLE_64K_ERASE     4                             ///< Flash Cycle 64K Sector Erase
+#define V_SPI_MEM_HSFSC_CYCLE_READ_SFDP     5                             ///< Flash Cycle Read SFDP
+#define V_SPI_MEM_HSFSC_CYCLE_READ_JEDEC_ID 6                             ///< Flash Cycle Read JEDEC ID
+#define V_SPI_MEM_HSFSC_CYCLE_WRITE_STATUS  7                             ///< Flash Cycle Write Status
+#define V_SPI_MEM_HSFSC_CYCLE_READ_STATUS   8                             ///< Flash Cycle Read Status
+#define B_SPI_MEM_HSFSC_CYCLE_FGO           BIT16                         ///< Flash Cycle Go.
+#define B_SPI_MEM_HSFSC_FLOCKDN             BIT15                         ///< Flash Configuration Lock-Down
+#define B_SPI_MEM_HSFSC_FDV                 BIT14                         ///< Flash Descriptor Valid, once valid software can use hareware sequencing regs
+#define B_SPI_MEM_HSFSC_FDOPSS              BIT13                         ///< Flash Descriptor Override Pin-Strap Status
+#define B_SPI_MEM_HSFSC_WRSDIS              BIT11                         ///< Write Status Disable
+#define B_SPI_MEM_HSFSC_SAF_MODE_ACTIVE     BIT7                          ///< Indicates flash is attached either directly to the PCH via the SPI bus or EC/BMC
+#define B_SPI_MEM_HSFSC_SCIP                BIT5                          ///< SPI cycle in progress
+#define B_SPI_MEM_HSFSC_SAF_DLE             BIT4                          ///< SAF Data length error
+#define B_SPI_MEM_HSFSC_SAF_ERROR           BIT3                          ///< SAF Error
+#define B_SPI_MEM_HSFSC_AEL                 BIT2                          ///< Access Error Log
+#define B_SPI_MEM_HSFSC_FCERR               BIT1                          ///< Flash Cycle Error
+#define B_SPI_MEM_HSFSC_FDONE               BIT0                          ///< Flash Cycle Done
+#define R_SPI_MEM_FADDR                     0x08                          ///< SPI Flash Address
+#define B_SPI_MEM_FADDR_MASK                0x07FFFFFF                    ///< SPI Flash Address Mask (0~26bit)
+#define R_SPI_MEM_DLOCK                     0x0C                          ///< Discrete Lock Bits
+#define B_SPI_MEM_DLOCK_PR0LOCKDN           BIT8                          ///< PR0LOCKDN
+#define R_SPI_MEM_FDATA00                   0x10                          ///< SPI Data 00 (32 bits)
+#define R_SPI_MEM_FRAP                      0x50                          ///< Flash Region Access Permissions Register
+#define B_SPI_MEM_FRAP_BRWA_MASK            0x0000FF00                    ///< BIOS Region Write Access MASK, Region0~7 - 0: Flash Descriptor; 1: BIOS; 2: ME; 3: GbE; 4: PlatformData
+#define N_SPI_MEM_FRAP_BRWA                 8                             ///< BIOS Region Write Access bit position
+#define B_SPI_MEM_FRAP_BRRA_MASK            0x000000FF                    ///< BIOS Region Read Access MASK, Region0~7 - 0: Flash Descriptor; 1: BIOS; 2: ME; 3: GbE; 4: PlatformData
+#define B_SPI_MEM_FRAP_BMRAG_MASK           0x00FF0000                    ///< BIOS Master Read Access Grant
+#define B_SPI_MEM_FRAP_BMWAG_MASK           0xFF000000                    ///< BIOS Master Write Access Grant
+#define R_SPI_MEM_FREG0_FLASHD              0x54                          ///< Flash Region 0(Flash Descriptor)(32bits)
+#define R_SPI_MEM_FREG3_GBE                 0x60                          ///< Flash Region 3(GbE)(32bits)
+#define S_SPI_MEM_FREGX                     4                             ///< Size of Flash Region register
+#define B_SPI_MEM_FREGX_LIMIT_MASK          0x7FFF0000                    ///< Flash Region Limit [30:16] represents [26:12], [11:0] are assumed to be FFFh
+#define N_SPI_MEM_FREGX_LIMIT               16                            ///< Region limit bit position
+#define N_SPI_MEM_FREGX_LIMIT_REPR          12                            ///< Region limit bit represents position
+#define B_SPI_MEM_FREGX_BASE_MASK           0x00007FFF                    ///< Flash Region Base, [14:0] represents [26:12]
+#define N_SPI_MEM_FREGX_BASE                0                             ///< Region base bit position
+#define N_SPI_MEM_FREGX_BASE_REPR           12                            ///< Region base bit represents position
+#define R_SPI_MEM_PR0                       0x84                          ///< Protected Region 0 Register
+#define S_SPI_MEM_PRX                       4                             ///< Protected Region X Register size
+#define B_SPI_MEM_PRX_WPE                   BIT31                         ///< Write Protection Enable
+#define B_SPI_MEM_PRX_PRL_MASK              0x7FFF0000                    ///< Protected Range Limit Mask, [30:16] here represents upper limit of address [26:12]
+#define N_SPI_MEM_PRX_PRL                   16                            ///< Protected Range Limit bit position
+#define B_SPI_MEM_PRX_RPE                   BIT15                         ///< Read Protection Enable
+#define B_SPI_MEM_PRX_PRB_MASK              0x00007FFF                    ///< Protected Range Base Mask, [14:0] here represents base limit of address [26:12]
+#define N_SPI_MEM_PRX_PRB                   0                             ///< Protected Range Base bit position
+#define R_SPI_MEM_FDOC                      0xB4                          ///< Flash Descriptor Observability Control Register(32 bits)
+#define B_SPI_MEM_FDOC_FDSS_MASK            (BIT14 | BIT13 | BIT12)       ///< Flash Descritor Section Select
+#define V_SPI_MEM_FDOC_FDSS_FSDM            0x0000                        ///< Flash Signature and Descriptor Map
+#define V_SPI_MEM_FDOC_FDSS_COMP            0x1000                        ///< Component
+#define V_SPI_MEM_FDOC_FDSS_MSTR            0x3000                        ///< Master
+#define B_SPI_MEM_FDOC_FDSI_MASK            0x0FFC                        ///< Flash Descriptor Section Index
+#define R_SPI_MEM_FDOD                      0xB8                          ///< Flash Descriptor Observability Data Register(32 bits)
+#define R_SPI_MEM_SFDP0_VSCC0               0xC4                          ///< Vendor Specific Component Capabilities Register(32 bits)
+#define B_SPI_MEM_SFDPX_VSCCX_CPPTV         BIT31                         ///< Component Property Parameter Table Valid
+#define B_SPI_MEM_SFDP0_VSCC0_VCL           BIT30                         ///< Vendor Component Lock
+#define B_SPI_MEM_SFDPX_VSCCX_EO_64K        BIT29                         ///< 64k Erase valid (EO_64k_valid)
+#define R_SPI_MEM_SFDP1_VSCC1               0xC8                          ///< Vendor Specific Component Capabilities Register(32 bits)
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Library/PeiDxeSmmSpiAccessLib/PeiDxeSmmSpiAccessLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Library/PeiDxeSmmSpiAccessLib/PeiDxeSmmSpiAccessLib.inf
new file mode 100644
index 0000000000..bba0b1fef3
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Library/PeiDxeSmmSpiAccessLib/PeiDxeSmmSpiAccessLib.inf
@@ -0,0 +1,33 @@
+## @file
+# Component description file for PCH SPI access library
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION     = 0x00010017
+BASE_NAME       = PeiDxeSmmSpiAccessLib
+FILE_GUID       = A6D4C05A-F6CB-46D5-4BA1-8C47B139DCA6
+VERSION_STRING  = 1.0
+MODULE_TYPE     = BASE
+LIBRARY_CLASS   = SpiAccessLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PciSegmentLib
+PchPciBdfLib
+PchPcrLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+SpiAccessLib.c
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Library/PeiDxeSmmSpiAccessLib/SpiAccessLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Library/PeiDxeSmmSpiAccessLib/SpiAccessLib.c
new file mode 100644
index 0000000000..c91b9aaf4d
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Library/PeiDxeSmmSpiAccessLib/SpiAccessLib.c
@@ -0,0 +1,477 @@
+/** @file
+  SPI library for abstraction of SPI HW registers accesses
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <IndustryStandard/Pci22.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/SpiAccessLib.h>
+#include <Library/PchPciBdfLib.h>
+#include <Library/PchPcrLib.h>
+#include <Register/SpiRegs.h>
+#include <Register/FlashRegs.h>
+#include <Register/PchRegs.h>
+#include <Register/PchPcrRegs.h>
+#include <Register/PchDmiRegs.h>
+
+/**
+  Checks if PCH SPI Controler is present and available
+
+  @retval TRUE    PCH SPI controller is avaialable
+  @retval FALSE   PCH SPI controller is not available
+**/
+BOOLEAN
+SpiIsControllerAvailable (
+  VOID
+  )
+{
+  //
+  // Checks for SPI controller
+  //
+  return (PciSegmentRead16 (SpiPciCfgBase () + PCI_VENDOR_ID_OFFSET) != 0xFFFF);
+}
+
+/**
+  Returns PCH SPI BAR0 value
+
+  @retval  UINT32  PCH SPI BAR0 value
+**/
+UINT32
+SpiGetBar0 (
+  VOID
+  )
+{
+  UINT32  SpiBar0;
+
+  ASSERT (SpiIsControllerAvailable ());
+  SpiBar0 = PciSegmentRead32 (SpiPciCfgBase () + R_SPI_CFG_BAR0) & ~B_SPI_CFG_BAR0_MASK;
+  ASSERT (SpiBar0 != 0);
+
+  return SpiBar0;
+}
+
+/**
+  Reads given descriptor section and returns value
+
+  @param[in] UINT16   Descriptor section
+  @param[in] UINT16   Offset
+
+  @retval UINT32      Read value from a section under given offset
+**/
+STATIC
+UINT32
+SpiReadDescriptor (
+  IN  UINT16  DescriptorSection,
+  IN  UINT16  Offset
+  )
+{
+  UINT32  SpiBar0;
+  SpiBar0 = SpiGetBar0 ();
+
+  MmioWrite32 (SpiBar0 + R_SPI_MEM_FDOC, (DescriptorSection | Offset));
+  return MmioRead32 (SpiBar0 + R_SPI_MEM_FDOD);
+}
+
+/**
+  Returns descriptor signature
+
+  @retval UINT32    Descriptor signature
+**/
+UINT32
+SpiGetDescriptorSignature (
+  VOID
+  )
+{
+  //
+  // Read Descriptor offset 0x10 - To get Descriptor Signature
+  // Signature section 0x0000 + offset 0x0 which points to Descriptor offset 0x10
+  //
+  return SpiReadDescriptor (V_SPI_MEM_FDOC_FDSS_FSDM, 0x0);
+}
+
+/**
+  Returns supported features and R/W frequencies of Flash Component
+
+  @retval UINT32    Flash Component features descriptor
+**/
+UINT32
+SpiGetFlashComponentDescription (
+  VOID
+  )
+{
+  //
+  // Read Descriptor offset 0x30 - To get supported features and R/W frequencies
+  // Component section 0x1000 + offset 0x0 which points to Descriptor offset 0x30
+  //
+  return SpiReadDescriptor (V_SPI_MEM_FDOC_FDSS_COMP, 0x0);
+}
+
+/**
+  Returns number of Flash Components
+
+  @retval UINT32    Flash components number
+**/
+UINT32
+SpiGetFlashComponentsNumber (
+  VOID
+  )
+{
+  //
+  // Read Descriptor offset 0x14 - To get number of components
+  // Signature section 0x0000 + offset 0x4 which points to Descriptor offset 0x14
+  //
+  return ((SpiReadDescriptor (V_SPI_MEM_FDOC_FDSS_FSDM, R_FLASH_FDBAR_FLASH_MAP0) & B_FLASH_FDBAR_NC) >> N_FLASH_FDBAR_NC);
+}
+
+/**
+  Returns total Flash size with regards to number of flash components
+
+  @retval UINT32    Total Flash Memory size
+**/
+UINT32
+SpiGetTotalFlashSize (
+  VOID
+  )
+{
+  UINT32  Data32;
+  UINT32  ComponentsNumber;
+  UINT32  TotalFlashSize;
+
+  Data32 = SpiGetFlashComponentDescription ();
+  ComponentsNumber = SpiGetFlashComponentsNumber ();
+
+  TotalFlashSize = (V_FLASH_FLCOMP_COMP_512KB << ((UINT8) (Data32 & B_FLASH_FLCOMP_COMP0_MASK)));
+  if (ComponentsNumber == 1) {
+    TotalFlashSize += (V_FLASH_FLCOMP_COMP_512KB << ((UINT8) ((Data32 & B_FLASH_FLCOMP_COMP1_MASK) >> 4)));
+  }
+
+  return TotalFlashSize;
+}
+
+/**
+  Checks BIOS lock bits for proper value and checks if write protection is enabled
+  Expected vales are: LE bit set, EISS bit set and WPD bit cleared
+
+  @retval  TRUE    All protection bits are set correctly
+  @retval  FALSE   Not all protection bits had exepcted values
+**/
+BOOLEAN
+SpiIsWriteProtectionEnabled (
+  VOID
+  )
+{
+  UINT32  BiosControl;
+  BiosControl = PciSegmentRead32 (SpiPciCfgBase () + R_SPI_CFG_BC);
+
+  DEBUG ((DEBUG_INFO, "SPI BIOS CONTROL LE: %x\n", (BiosControl & B_SPI_CFG_BC_LE) != 0 ));
+  DEBUG ((DEBUG_INFO, "SPI BIOS CONTROL WPD: %x\n", (BiosControl & B_SPI_CFG_BC_WPD) != 0 ));
+  DEBUG ((DEBUG_INFO, "SPI BIOS CONTROL EISS: %x\n", (BiosControl & B_SPI_CFG_BC_EISS) != 0 ));
+
+  return (((BiosControl & B_SPI_CFG_BC_LE) != 0) &&
+          ((BiosControl & B_SPI_CFG_BC_WPD) == 0) &&
+          ((BiosControl & B_SPI_CFG_BC_EISS) != 0));
+}
+
+/**
+  Returns status of BIOS Interface Lockdown
+
+  @retval TRUE  BIOS Interface Lockdown is enabled
+  @retval FALSE BIOS Interface Lockdown is disabled
+**/
+BOOLEAN
+SpiIsBiosInterfaceLockdownEnabled (
+  VOID
+  )
+{
+  return !!(PciSegmentRead32 (SpiPciCfgBase () + R_SPI_CFG_BC) & B_SPI_CFG_BC_BILD);
+}
+
+/**
+  Returns Flash Descriptor Override Pin Strap status
+
+  @retval TRUE     Flash Descriptor override is enabled
+  @retval FALSE    Flash Descriptor override is disabled
+**/
+BOOLEAN
+SpiIsFlashDescriptorOverrideEnabled (
+  VOID
+  )
+{
+  UINT32  SpiBar0;
+  SpiBar0 = SpiGetBar0 ();
+
+  return !!(MmioRead16 (SpiBar0 + R_SPI_MEM_HSFSC) & B_SPI_MEM_HSFSC_FDOPSS);
+}
+
+/**
+  Returns Flash Configuration Lock Down bit status
+
+  @retval TRUE    Flash Configuration Lock Down bit is set
+  @retval FALSE   Flash Configuration Lock Down bit is not set
+**/
+BOOLEAN
+SpiIsFlashConfigurationLockDownEnabled (
+  VOID
+  )
+{
+  UINT32  SpiBar0;
+  SpiBar0 = SpiGetBar0 ();
+
+  return !!(MmioRead16 (SpiBar0 + R_SPI_MEM_HSFSC) & B_SPI_MEM_HSFSC_FLOCKDN);
+}
+
+/**
+  Returns Top Swap functionality enable state
+
+  @retval TRUE    Top Swap is enabled
+  @retval FALSE   Top Swap is disabled
+**/
+BOOLEAN
+SpiIsTopSwapEnabled (
+  VOID
+  )
+{
+  return !!(PciSegmentRead32 (SpiPciCfgBase () + R_SPI_CFG_BC) & B_SPI_CFG_BC_TSS);
+}
+
+/**
+  Return Component Property Parameter Table for a given component number
+
+  @param[in]  ComponentNumber   SPI Component number
+  @param[out] CppTable          Component Poperty Parameter Table value
+
+  @retval TRUE  Vendor Specific Component Capabilities Register value was read
+  @reval  FALSE Vendor Specific Component Capabilities Register value was not present
+**/
+BOOLEAN
+SpiGetComponentPropertyParameterTable (
+  IN  UINT8  ComponentNumber,
+  OUT UINT32 *CppTable
+  )
+{
+  UINT32 SpiBar0;
+  UINT32 Data32;
+  SpiBar0 = SpiGetBar0 ();
+
+  //
+  // More than 2 components not supported
+  //
+  switch (ComponentNumber) {
+    case 0:
+      *CppTable = MmioRead32 (SpiBar0 + R_SPI_MEM_SFDP0_VSCC0);
+      return TRUE;
+    case 1:
+      Data32    = SpiReadDescriptor (V_SPI_MEM_FDOC_FDSS_FSDM, R_FLASH_FDBAR_FLASH_MAP0);
+      *CppTable = MmioRead32 (SpiBar0 + R_SPI_MEM_SFDP1_VSCC1);
+      return !!(Data32 & BIT8);
+    default:
+      return FALSE;
+  }
+}
+
+/**
+  Returns valid bit status in given Component Property Parameter Table
+
+  @param[in] CppTable          Component Poperty Parameter Table value
+
+  @retval TRUE    Valid bit is set
+  @reval  FALSE   Valid bit is not set
+**/
+BOOLEAN
+SpiIsCppValidBitSet (
+  IN UINT32  CppTable
+  )
+{
+  return !!(CppTable & B_SPI_MEM_SFDPX_VSCCX_CPPTV);
+}
+
+/**
+  Checks if Flash Descriptor is valid
+
+  @retval TRUE  Flash Descriptor is valid
+  @retval FALSE Flash Descriptor is invalid
+**/
+BOOLEAN
+SpiIsFlashDescriptorValid (
+  VOID
+  )
+{
+  UINT32 SpiBar0;
+  SpiBar0 = SpiGetBar0 ();
+
+  return !!(MmioRead32 (SpiBar0 + R_SPI_MEM_HSFSC) & B_SPI_MEM_HSFSC_FDV);
+}
+
+/**
+  Reads and returns value from Flash Region Access Permissions Register (FRAP)
+
+  @retval UINT32  Flash Region Access Permissions Register value
+**/
+STATIC
+UINT32
+SpiGetFlashRegionAccessPermissions (
+  VOID
+  )
+{
+  return MmioRead32 (SpiGetBar0 () + R_SPI_MEM_FRAP);
+}
+
+/**
+  Returns masked BIOS Master Read Access
+
+  @retval UINT32    Already masked BIOS Master Read Access
+**/
+UINT32
+SpiGetMasterReadAccess (
+  VOID
+  )
+{
+  UINT32 Data32;
+  Data32 = SpiGetFlashRegionAccessPermissions () & B_SPI_MEM_FRAP_BMRAG_MASK;
+  DEBUG ((DEBUG_INFO, "BMRAG 0x%x\n", Data32));
+
+  return Data32;
+}
+
+/**
+  Returns masked BIOS Master Write Access
+
+  @retval UINT32    Already masked BIOS Master Write Access
+**/
+UINT32
+SpiGetMasterWriteAccess (
+  VOID
+  )
+{
+  UINT32 Data32;
+  Data32 = SpiGetFlashRegionAccessPermissions () & B_SPI_MEM_FRAP_BMWAG_MASK;
+  DEBUG ((DEBUG_INFO, "BMWAG 0x%x\n", Data32));
+
+  return Data32;
+}
+
+/**
+  Returns GbE Region Access rights
+
+  @retval UINT32    GbE Region access rights
+**/
+UINT32
+SpiGetGbeRegionAccess (
+  VOID
+  )
+{
+  UINT32 Data32;
+
+  Data32 = SpiReadDescriptor (V_SPI_MEM_FDOC_FDSS_MSTR, 0x8);
+  DEBUG ((DEBUG_INFO, "GbE Region Access 0x%x\n", Data32));
+
+  return Data32;
+}
+
+/**
+  Returns CSME region access rights
+
+  @retval UINT32    CSME Region Access rights
+**/
+UINT32
+SpiGetCsmeRegionAccess (
+  VOID
+  )
+{
+  UINT32 Data32;
+
+  Data32 = SpiReadDescriptor (V_SPI_MEM_FDOC_FDSS_MSTR, 0x4);
+  DEBUG ((DEBUG_INFO, "CSME Region Access 0x%x\n", Data32));
+
+  return Data32;
+}
+
+/**
+  Returns EC region access right
+
+  @retval UINT32     EC Region access rights
+**/
+UINT32
+SpiGetEcRegionAccess (
+  VOID
+  )
+{
+  UINT32 Data32;
+
+  Data32 = SpiReadDescriptor (V_SPI_MEM_FDOC_FDSS_MSTR, 0x10);
+  DEBUG ((DEBUG_INFO, "EC Region Access 0x%x\n", Data32));
+
+  return Data32;
+}
+
+/**
+  Checks if Slave Attached Flash (SAF) mode is active
+
+  @retval TRUE    SAF mode is active
+  @retval FALSE   SAF mode is not active
+**/
+BOOLEAN
+SpiIsSafModeActive (
+  VOID
+  )
+{
+  UINT32 SpiBar0;
+  SpiBar0 = SpiGetBar0 ();
+
+  return !!(MmioRead32 (SpiBar0 + R_SPI_MEM_HSFSC) & B_SPI_MEM_HSFSC_SAF_MODE_ACTIVE);
+}
+
+/**
+  Checks validity of GbE region
+
+  @retval TRUE    GbE region is valid
+  @retval FALSE   GbE regios in invalid
+**/
+BOOLEAN
+SpiIsGbeRegionValid (
+  VOID
+  )
+{
+  UINT32  SpiBar0;
+  SpiBar0 = SpiGetBar0 ();
+
+  if (MmioRead32 (SpiBar0 + R_SPI_MEM_FREG3_GBE) != B_SPI_MEM_FREGX_BASE_MASK) {
+    return TRUE;
+  }
+  return FALSE;
+}
+
+/**
+  Returns TRUE if BIOS Boot Strap is set to SPI
+
+  @retval TRUE    BIOS Boot strap is set to SPI
+  @retval FALSE   BIOS Boot strap is set to LPC/eSPI
+**/
+BOOLEAN
+SpiIsBiosBootFromSpi (
+  VOID
+  )
+{
+  return !!(((PciSegmentRead8 (SpiPciCfgBase () + R_SPI_CFG_BC) & B_SPI_CFG_BC_BBS) >> N_SPI_CFG_BC_BBS) == V_SPI_CFG_BC_BBS_SPI);
+}
+
+/**
+  Check SPI write status disable is set
+
+  @retval TRUE    Write status disable is set
+  @retval FALSE   Write status disable is not set
+**/
+BOOLEAN
+SpiIsWriteStatusDisable (
+  VOID
+  )
+{
+  return !!(MmioRead32 (SpiGetBar0 () + R_SPI_MEM_HSFSC) & B_SPI_MEM_HSFSC_WRSDIS);
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/BaseSpiCommonLib/BaseSpiCommonLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/BaseSpiCommonLib/BaseSpiCommonLib.inf
new file mode 100644
index 0000000000..a1a5467745
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/BaseSpiCommonLib/BaseSpiCommonLib.inf
@@ -0,0 +1,31 @@
+## @file
+#  Component description file for the PchSpiCommonLib
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BaseSpiCommonLib
+  FILE_GUID                      = A37CB67E-7D85-45B3-B07E-BF65BDB603E8
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SpiCommonLib
+
+[Sources]
+  SpiCommon.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  TigerlakeSiliconPkg/SiPkg.dec
+
+[LibraryClasses]
+  IoLib
+  DebugLib
+  PmcLib
+  PchPciBdfLib
+  SpiAccessLib
+
+[Pcd]
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/BaseSpiCommonLib/SpiCommon.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/BaseSpiCommonLib/SpiCommon.c
new file mode 100644
index 0000000000..954b349e7c
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/BaseSpiCommonLib/SpiCommon.c
@@ -0,0 +1,1115 @@
+/** @file
+  PCH SPI Common Driver implements the SPI Host Controller Compatibility Interface.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Uefi/UefiBaseType.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Library/PmcLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Protocol/Spi.h>
+#include <Library/SpiCommonLib.h>
+#include <Register/PchRegs.h>
+#include <Register/SpiRegs.h>
+#include <Register/FlashRegs.h>
+#include <Register/PmcRegs.h>
+#include <Library/PchPciBdfLib.h>
+#include <Library/SpiAccessLib.h>
+
+/**
+  Initialize an SPI protocol instance.
+
+  @param[in] SpiInstance          Pointer to SpiInstance to initialize
+
+  @retval EFI_SUCCESS             The protocol instance was properly initialized
+  @exception EFI_UNSUPPORTED      The PCH is not supported by this module
+**/
+EFI_STATUS
+SpiProtocolConstructor (
+  IN     SPI_INSTANCE       *SpiInstance
+  )
+{
+  UINTN           PchSpiBar0;
+  UINT32          Data32;
+  UINT16          Mdtba;
+  EFI_STATUS      Status;
+
+  //
+  // Initialize the SPI protocol instance
+  //
+  SpiInstance->Signature                    = PCH_SPI_PRIVATE_DATA_SIGNATURE;
+  SpiInstance->Handle                       = NULL;
+  SpiInstance->SpiProtocol.Revision         = PCH_SPI_SERVICES_REVISION;
+  SpiInstance->SpiProtocol.FlashRead        = SpiProtocolFlashRead;
+  SpiInstance->SpiProtocol.FlashWrite       = SpiProtocolFlashWrite;
+  SpiInstance->SpiProtocol.FlashErase       = SpiProtocolFlashErase;
+  SpiInstance->SpiProtocol.FlashReadSfdp    = SpiProtocolFlashReadSfdp;
+  SpiInstance->SpiProtocol.FlashReadJedecId = SpiProtocolFlashReadJedecId;
+  SpiInstance->SpiProtocol.FlashWriteStatus = SpiProtocolFlashWriteStatus;
+  SpiInstance->SpiProtocol.FlashReadStatus  = SpiProtocolFlashReadStatus;
+  SpiInstance->SpiProtocol.GetRegionAddress = SpiProtocolGetRegionAddress;
+  SpiInstance->SpiProtocol.ReadPchSoftStrap = SpiProtocolReadPchSoftStrap;
+  SpiInstance->SpiProtocol.ReadCpuSoftStrap = SpiProtocolReadCpuSoftStrap;
+
+  SpiInstance->PchSpiBase = SpiPciCfgBase ();
+
+  SpiInstance->PchAcpiBase = PmcGetAcpiBase ();
+  ASSERT (SpiInstance->PchAcpiBase != 0);
+
+  PchSpiBar0 = PciSegmentRead32 (SpiInstance->PchSpiBase + R_SPI_CFG_BAR0) & ~(B_SPI_CFG_BAR0_MASK);
+  if (PchSpiBar0 == 0) {
+    DEBUG ((DEBUG_ERROR, "ERROR : PchSpiBar0 is invalid!\n"));
+    ASSERT (FALSE);
+  }
+
+  if ((MmioRead32 (PchSpiBar0 + R_SPI_MEM_HSFSC) & B_SPI_MEM_HSFSC_FDV) == 0) {
+    DEBUG ((DEBUG_ERROR, "ERROR : SPI Flash Signature invalid, cannot use the Hardware Sequencing registers!\n"));
+    ASSERT (FALSE);
+  }
+
+  //
+  // Get Region 0 - 7 read Permission bits, region 8 and above are not permitted.
+  //
+  SpiInstance->ReadPermission = MmioRead8 (PchSpiBar0 + R_SPI_MEM_FRAP) & B_SPI_MEM_FRAP_BRRA_MASK;
+  DEBUG ((DEBUG_INFO, "Flash Region read Permission : %0x\n", SpiInstance->ReadPermission));
+  //
+  // Get Region 0 - 7 write Permission bits, region 8 and above are not permitted.
+  //
+  SpiInstance->WritePermission = (UINT8) ((MmioRead16 (PchSpiBar0 + R_SPI_MEM_FRAP) &
+                                           B_SPI_MEM_FRAP_BRWA_MASK) >> N_SPI_MEM_FRAP_BRWA);
+  DEBUG ((DEBUG_INFO, "Flash Region write Permission : %0x\n", SpiInstance->WritePermission));
+
+  SpiInstance->SfdpVscc0Value = MmioRead32 (PchSpiBar0 + R_SPI_MEM_SFDP0_VSCC0);
+  DEBUG ((DEBUG_INFO, "Component 0 SFDP VSCC value : %0x\n", SpiInstance->SfdpVscc0Value));
+  SpiInstance->SfdpVscc1Value = MmioRead32 (PchSpiBar0 + R_SPI_MEM_SFDP1_VSCC1);
+  DEBUG ((DEBUG_INFO, "Component 1 SFDP VSCC value : %0x\n", SpiInstance->SfdpVscc1Value));
+
+  //
+  // Select to Flash Map 0 Register to get the number of flash Component
+  //
+  MmioAndThenOr32 (
+    PchSpiBar0 + R_SPI_MEM_FDOC,
+    (UINT32) (~(B_SPI_MEM_FDOC_FDSS_MASK | B_SPI_MEM_FDOC_FDSI_MASK)),
+    (UINT32) (V_SPI_MEM_FDOC_FDSS_FSDM | R_FLASH_FDBAR_FLASH_MAP0)
+    );
+
+  //
+  // Copy Zero based Number Of Components
+  //
+  SpiInstance->NumberOfComponents = (UINT8) ((MmioRead16 (PchSpiBar0 + R_SPI_MEM_FDOD) & B_FLASH_FDBAR_NC) >> N_FLASH_FDBAR_NC);
+  DEBUG ((DEBUG_INFO, "Component Number : %0x\n", SpiInstance->NumberOfComponents + 1));
+
+  MmioAndThenOr32 (
+    PchSpiBar0 + R_SPI_MEM_FDOC,
+    (UINT32) (~(B_SPI_MEM_FDOC_FDSS_MASK | B_SPI_MEM_FDOC_FDSI_MASK)),
+    (UINT32) (V_SPI_MEM_FDOC_FDSS_COMP | R_FLASH_FCBA_FLCOMP)
+    );
+
+  //
+  // Copy Component 0 Density
+  //
+  Data32 = MmioRead32 (PchSpiBar0 + R_SPI_MEM_FDOD);
+  if (SpiInstance->NumberOfComponents > 0) {
+    SpiInstance->Component1StartAddr = V_FLASH_FLCOMP_COMP_512KB <<
+      (Data32 & B_FLASH_FLCOMP_COMP0_MASK);
+    DEBUG ((DEBUG_INFO, "Component 1 StartAddr : %0x\n", SpiInstance->Component1StartAddr));
+    SpiInstance->TotalFlashSize = SpiInstance->Component1StartAddr +
+      (V_FLASH_FLCOMP_COMP_512KB <<
+      ((Data32 & B_FLASH_FLCOMP_COMP1_MASK) >>
+      N_FLASH_FLCOMP_COMP1));
+  } else {
+    SpiInstance->TotalFlashSize = V_FLASH_FLCOMP_COMP_512KB <<
+      (Data32 & B_FLASH_FLCOMP_COMP0_MASK);
+  }
+  DEBUG ((DEBUG_INFO, "Total Flash Size : %0x\n", SpiInstance->TotalFlashSize));
+
+  //
+  // Select FLASH_MAP1 to get Flash PCH Strap Base Address
+  //
+  MmioAndThenOr32 (
+    (PchSpiBar0 + R_SPI_MEM_FDOC),
+    (UINT32) (~(B_SPI_MEM_FDOC_FDSS_MASK | B_SPI_MEM_FDOC_FDSI_MASK)),
+    (UINT32) (V_SPI_MEM_FDOC_FDSS_FSDM | R_FLASH_FDBAR_FLASH_MAP1)
+    );
+  //
+  // Align FPSBA with address bits for the PCH Strap portion of flash descriptor
+  //
+  Data32 = MmioRead32 (PchSpiBar0 + R_SPI_MEM_FDOD);
+  SpiInstance->PchStrapBaseAddr = (UINT16) (((Data32 & B_FLASH_FDBAR_FPSBA)
+                                             >> N_FLASH_FDBAR_FPSBA)
+                                            << N_FLASH_FDBAR_FPSBA_REPR);
+  DEBUG ((DEBUG_INFO, "PchStrapBaseAddr : %0x\n", SpiInstance->PchStrapBaseAddr));
+  ASSERT (SpiInstance->PchStrapBaseAddr != 0);
+  //
+  // PCH Strap Length, [31:24] represents number of Dwords
+  //
+  SpiInstance->PchStrapSize = (UINT16) (((Data32 & B_FLASH_FDBAR_PCHSL)
+                                         >> N_FLASH_FDBAR_PCHSL)
+                                        * sizeof (UINT32));
+  DEBUG ((DEBUG_INFO, "PchStrapSize : %0x\n", SpiInstance->PchStrapSize));
+
+  //
+  // Select FLASH_MAP2 to get Flash CPU Strap Base Address
+  //
+  MmioAndThenOr32 (
+    (PchSpiBar0 + R_SPI_MEM_FDOC),
+    (UINT32) (~(B_SPI_MEM_FDOC_FDSS_MASK | B_SPI_MEM_FDOC_FDSI_MASK)),
+    (UINT32) (V_SPI_MEM_FDOC_FDSS_FSDM | R_FLASH_FDBAR_FLASH_MAP2)
+    );
+  //
+  // Align FPSBA with address bits for the CPU Strap portion of flash descriptor
+  //
+  Data32 = MmioRead32 (PchSpiBar0 + R_SPI_MEM_FDOD);
+  //
+  // CPU Strap Length, [23:16] represents number of Dwords
+  //
+  SpiInstance->CpuStrapSize = (UINT16) (((Data32 & B_FLASH_FDBAR_CPUSL)
+                                         >> N_FLASH_FDBAR_CPUSL)
+                                        * sizeof (UINT32));
+
+  //
+  // CPU Strap Address [11:2] represent offset from MDTBA
+  //
+  SpiInstance->CpuStrapBaseAddr = (UINT16) ((Data32 & B_FLASH_FDBAR_FCPUSBA) >> N_FLASH_FDBAR_FCPUSBA);
+  ASSERT (SpiInstance->CpuStrapBaseAddr != 0);
+
+  if (SpiInstance->CpuStrapBaseAddr != 0x300) {
+    Status = SpiProtocolFlashRead (&(SpiInstance->SpiProtocol), FlashRegionAll, R_FLASH_UMAP1, sizeof (Data32), (UINT8 *) (&Data32));
+    ASSERT_EFI_ERROR (Status);
+    Mdtba = (UINT16)(((Data32 & B_FLASH_UMAP1_MDTBA) >> N_FLASH_UMAP1_MDTBA) << N_FLASH_UMAP1_MDTBA_REPR);
+    DEBUG ((DEBUG_INFO, "Mdtba : %0x\n", Mdtba));
+    // Add MDTBA offset for final address of CPU Straps
+    SpiInstance->CpuStrapBaseAddr += Mdtba;
+  }
+
+  DEBUG ((DEBUG_INFO, "CpuStrapBaseAddr : %0x\n", SpiInstance->CpuStrapBaseAddr));
+  DEBUG ((DEBUG_INFO, "CpuStrapSize : %0x\n", SpiInstance->CpuStrapSize));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Delay for at least the request number of microseconds for Runtime usage.
+
+  @param[in] ABase                Acpi base address
+  @param[in] Microseconds         Number of microseconds to delay.
+
+**/
+VOID
+EFIAPI
+PchPmTimerStallRuntimeSafe (
+  IN  UINT16  ABase,
+  IN  UINTN   Microseconds
+  )
+{
+  UINTN   Ticks;
+  UINTN   Counts;
+  UINTN   CurrentTick;
+  UINTN   OriginalTick;
+  UINTN   RemainingTick;
+
+  if (Microseconds == 0) {
+    return;
+  }
+
+  OriginalTick   = IoRead32 ((UINTN) (ABase + R_ACPI_IO_PM1_TMR)) & B_ACPI_IO_PM1_TMR_VAL;
+  CurrentTick    = OriginalTick;
+
+  //
+  // The timer frequency is 3.579545 MHz, so 1 ms corresponds 3.58 clocks
+  //
+  Ticks = Microseconds * 358 / 100 + OriginalTick + 1;
+
+  //
+  // The loops needed by timer overflow
+  //
+  Counts = Ticks / V_ACPI_IO_PM1_TMR_MAX_VAL;
+
+  //
+  // Remaining clocks within one loop
+  //
+  RemainingTick = Ticks % V_ACPI_IO_PM1_TMR_MAX_VAL;
+
+  //
+  // not intend to use TMROF_STS bit of register PM1_STS, because this adds extra
+  // one I/O operation, and maybe generate SMI
+  //
+  while ((Counts != 0) || (RemainingTick > CurrentTick)) {
+    CurrentTick = IoRead32 ((UINTN) (ABase + R_ACPI_IO_PM1_TMR)) & B_ACPI_IO_PM1_TMR_VAL;
+    //
+    // Check if timer overflow
+    //
+    if ((CurrentTick < OriginalTick)) {
+      if (Counts != 0) {
+        Counts--;
+      } else {
+        //
+        // If timer overflow and Counts equ to 0, that means we already stalled more than
+        // RemainingTick, break the loop here
+        //
+        break;
+      }
+    }
+
+    OriginalTick = CurrentTick;
+  }
+}
+
+/**
+  Wait execution cycle to complete on the SPI interface.
+
+  @param[in] This                 The SPI protocol instance
+  @param[in] PchSpiBar0           Spi MMIO base address
+  @param[in] ErrorCheck           TRUE if the SpiCycle needs to do the error check
+
+  @retval TRUE                    SPI cycle completed on the interface.
+  @retval FALSE                   Time out while waiting the SPI cycle to complete.
+                                  It's not safe to program the next command on the SPI interface.
+**/
+STATIC
+BOOLEAN
+WaitForSpiCycleComplete (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINTN              PchSpiBar0,
+  IN     BOOLEAN            ErrorCheck
+  )
+{
+  UINT64        WaitTicks;
+  UINT64        WaitCount;
+  UINT32        Data32;
+  SPI_INSTANCE  *SpiInstance;
+
+  SpiInstance       = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+
+  //
+  // Convert the wait period allowed into to tick count
+  //
+  WaitCount = SPI_WAIT_TIME / SPI_WAIT_PERIOD;
+  //
+  // Wait for the SPI cycle to complete.
+  //
+  for (WaitTicks = 0; WaitTicks < WaitCount; WaitTicks++) {
+    Data32 = MmioRead32 (PchSpiBar0 + R_SPI_MEM_HSFSC);
+    if ((Data32 & B_SPI_MEM_HSFSC_SCIP) == 0) {
+      MmioWrite32 (PchSpiBar0 + R_SPI_MEM_HSFSC, B_SPI_MEM_HSFSC_FCERR | B_SPI_MEM_HSFSC_FDONE);
+      if (((Data32 & B_SPI_MEM_HSFSC_FCERR) != 0) && (ErrorCheck == TRUE)) {
+        return FALSE;
+      } else {
+        return TRUE;
+      }
+    }
+    PchPmTimerStallRuntimeSafe (SpiInstance->PchAcpiBase, SPI_WAIT_PERIOD);
+  }
+  return FALSE;
+}
+
+/**
+  This function sends the programmed SPI command to the slave device.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] SpiRegionType        The SPI Region type for flash cycle which is listed in the Descriptor
+  @param[in] FlashCycleType       The Flash SPI cycle type list in HSFC (Hardware Sequencing Flash Control Register) register
+  @param[in] Address              The Flash Linear Address must fall within a region for which BIOS has access permissions.
+  @param[in] ByteCount            Number of bytes in the data portion of the SPI cycle.
+  @param[in,out] Buffer           Pointer to caller-allocated buffer containing the dada received or sent during the SPI cycle.
+
+  @retval EFI_SUCCESS             SPI command completes successfully.
+  @retval EFI_DEVICE_ERROR        Device error, the command aborts abnormally.
+  @retval EFI_ACCESS_DENIED       Some unrecognized or blocked command encountered in hardware sequencing mode
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+**/
+STATIC
+EFI_STATUS
+SendSpiCmd (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     FLASH_REGION_TYPE  FlashRegionType,
+  IN     FLASH_CYCLE_TYPE   FlashCycleType,
+  IN     UINT32             Address,
+  IN     UINT32             ByteCount,
+  IN OUT UINT8              *Buffer
+  )
+{
+  EFI_STATUS      Status;
+  UINT32          Index;
+  SPI_INSTANCE    *SpiInstance;
+  UINT64          SpiBaseAddress;
+  UINTN           PchSpiBar0;
+  UINT32          HardwareSpiAddr;
+  UINT32          FlashRegionSize;
+  UINT32          SpiDataCount;
+  UINT32          FlashCycle;
+  UINT8           BiosCtlSave;
+  UINT32          SmiEnSave;
+  UINT16          ABase;
+  UINT32          HsfstsCtl;
+
+  //
+  // For flash write, there is a requirement that all CPU threads are in SMM
+  // before the flash protection is disabled.
+  //
+  if ((FlashCycleType == FlashCycleWrite) || (FlashCycleType == FlashCycleErase)) {
+    if (!IsSpiFlashWriteGranted ()) {
+      return EFI_ACCESS_DENIED;
+    }
+  }
+
+  Status            = EFI_SUCCESS;
+  SpiInstance       = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+  SpiBaseAddress    = SpiInstance->PchSpiBase;
+  PchSpiBar0        = AcquireSpiBar0 (SpiInstance);
+  ABase             = SpiInstance->PchAcpiBase;
+
+  //
+  // Disable SMIs to make sure normal mode flash access is not interrupted by an SMI
+  // whose SMI handler accesses flash (e.g. for error logging)
+  //
+  // *** NOTE: if the SMI_LOCK bit is set (i.e., PMC PCI Offset A0h [4]='1'),
+  // clearing B_GBL_SMI_EN will not have effect. In this situation, some other
+  // synchronization methods must be applied here or in the consumer of the
+  // SendSpiCmd. An example method is disabling the specific SMI sources
+  // whose SMI handlers access flash before flash cycle and re-enabling the SMI
+  // sources after the flash cycle .
+  //
+  SmiEnSave   = IoRead32 ((UINTN) (ABase + R_ACPI_IO_SMI_EN));
+  IoWrite32 ((UINTN) (ABase + R_ACPI_IO_SMI_EN), SmiEnSave & (UINT32) (~B_ACPI_IO_SMI_EN_GBL_SMI));
+  BiosCtlSave = PciSegmentRead8 (SpiBaseAddress + R_SPI_CFG_BC) & B_SPI_CFG_BC_SRC;
+
+  //
+  // If it's write cycle, disable Prefetching, Caching and disable BIOS Write Protect
+  //
+  if ((FlashCycleType == FlashCycleWrite) ||
+      (FlashCycleType == FlashCycleErase)) {
+    Status = DisableBiosWriteProtect ();
+    if (EFI_ERROR (Status)) {
+      goto SendSpiCmdEnd;
+    }
+    PciSegmentAndThenOr8 (
+      SpiBaseAddress + R_SPI_CFG_BC,
+      (UINT8) (~B_SPI_CFG_BC_SRC),
+      (UINT8) (V_SPI_CFG_BC_SRC_PREF_DIS_CACHE_DIS <<  N_SPI_CFG_BC_SRC)
+      );
+  }
+  //
+  // Make sure it's safe to program the command.
+  //
+  if (!WaitForSpiCycleComplete (This, PchSpiBar0, FALSE)) {
+    Status = EFI_DEVICE_ERROR;
+    goto SendSpiCmdEnd;
+  }
+
+  //
+  // Check if Write Status isn't disabled in HW Sequencing
+  //
+  if (FlashCycleType == FlashCycleWriteStatus) {
+    HsfstsCtl = MmioRead32 (PchSpiBar0 + R_SPI_MEM_HSFSC);
+    if ((HsfstsCtl & B_SPI_MEM_HSFSC_WRSDIS) != 0) {
+      Status = EFI_ACCESS_DENIED;
+      goto SendSpiCmdEnd;
+    }
+  }
+
+  Status = SpiProtocolGetRegionAddress (This, FlashRegionType, &HardwareSpiAddr, &FlashRegionSize);
+  if (EFI_ERROR (Status)) {
+    goto SendSpiCmdEnd;
+  }
+  HardwareSpiAddr += Address;
+  if ((Address + ByteCount) > FlashRegionSize) {
+    Status = EFI_INVALID_PARAMETER;
+    goto SendSpiCmdEnd;
+  }
+
+  //
+  // Check for PCH SPI hardware sequencing required commands
+  //
+  FlashCycle = 0;
+  switch (FlashCycleType) {
+    case FlashCycleRead:
+      FlashCycle = (UINT32) (V_SPI_MEM_HSFSC_CYCLE_READ << N_SPI_MEM_HSFSC_CYCLE);
+      break;
+    case FlashCycleWrite:
+      FlashCycle = (UINT32) (V_SPI_MEM_HSFSC_CYCLE_WRITE << N_SPI_MEM_HSFSC_CYCLE);
+      break;
+    case FlashCycleErase:
+      if (((ByteCount % SIZE_4KB) != 0) ||
+          ((HardwareSpiAddr % SIZE_4KB) != 0)) {
+        ASSERT (FALSE);
+        Status = EFI_INVALID_PARAMETER;
+        goto SendSpiCmdEnd;
+      }
+      break;
+    case FlashCycleReadSfdp:
+      FlashCycle = (UINT32) (V_SPI_MEM_HSFSC_CYCLE_READ_SFDP << N_SPI_MEM_HSFSC_CYCLE);
+      break;
+    case FlashCycleReadJedecId:
+      FlashCycle = (UINT32) (V_SPI_MEM_HSFSC_CYCLE_READ_JEDEC_ID << N_SPI_MEM_HSFSC_CYCLE);
+      break;
+    case FlashCycleWriteStatus:
+      FlashCycle = (UINT32) (V_SPI_MEM_HSFSC_CYCLE_WRITE_STATUS << N_SPI_MEM_HSFSC_CYCLE);
+      break;
+    case FlashCycleReadStatus:
+      FlashCycle = (UINT32) (V_SPI_MEM_HSFSC_CYCLE_READ_STATUS << N_SPI_MEM_HSFSC_CYCLE);
+      break;
+    default:
+      //
+      // Unrecognized Operation
+      //
+      ASSERT (FALSE);
+      Status = EFI_INVALID_PARAMETER;
+      goto SendSpiCmdEnd;
+      break;
+  }
+
+  do {
+    SpiDataCount = ByteCount;
+    if ((FlashCycleType == FlashCycleRead) ||
+        (FlashCycleType == FlashCycleWrite) ||
+        (FlashCycleType == FlashCycleReadSfdp)) {
+      //
+      // Trim at 256 byte boundary per operation,
+      // - PCH SPI controller requires trimming at 4KB boundary
+      // - Some SPI chips require trimming at 256 byte boundary for write operation
+      // - Trimming has limited performance impact as we can read / write atmost 64 byte
+      //   per operation
+      //
+      if (HardwareSpiAddr + ByteCount > ((HardwareSpiAddr + BIT8) &~(BIT8 - 1))) {
+        SpiDataCount = (((UINT32) (HardwareSpiAddr) + BIT8) &~(BIT8 - 1)) - (UINT32) (HardwareSpiAddr);
+      }
+      //
+      // Calculate the number of bytes to shift in/out during the SPI data cycle.
+      // Valid settings for the number of bytes duing each data portion of the
+      // PCH SPI cycles are: 0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 24, 32, 40, 48, 56, 64
+      //
+      if (SpiDataCount >= 64) {
+        SpiDataCount = 64;
+      } else if ((SpiDataCount &~0x07) != 0) {
+        SpiDataCount = SpiDataCount &~0x07;
+      }
+    }
+    if (FlashCycleType == FlashCycleErase) {
+      if (((ByteCount / SIZE_64KB) != 0) &&
+          ((ByteCount % SIZE_64KB) == 0) &&
+          ((HardwareSpiAddr % SIZE_64KB) == 0)) {
+        if ((SpiInstance->NumberOfComponents == 0) ||
+            (HardwareSpiAddr < SpiInstance->Component1StartAddr)) {
+          //
+          // Check whether Component0 support 64k Erase
+          //
+          if ((SpiInstance->SfdpVscc0Value & B_SPI_MEM_SFDPX_VSCCX_EO_64K) != 0) {
+            SpiDataCount = SIZE_64KB;
+          } else {
+            SpiDataCount = SIZE_4KB;
+          }
+        } else {
+          //
+          // Check whether Component1 support 64k Erase
+          //
+          if ((SpiInstance->SfdpVscc1Value & B_SPI_MEM_SFDPX_VSCCX_EO_64K) != 0) {
+            SpiDataCount = SIZE_64KB;
+          } else {
+            SpiDataCount = SIZE_4KB;
+          }
+        }
+      } else {
+        SpiDataCount = SIZE_4KB;
+      }
+      if (SpiDataCount == SIZE_4KB) {
+        FlashCycle = (UINT32) (V_SPI_MEM_HSFSC_CYCLE_4K_ERASE << N_SPI_MEM_HSFSC_CYCLE);
+      } else {
+        FlashCycle = (UINT32) (V_SPI_MEM_HSFSC_CYCLE_64K_ERASE << N_SPI_MEM_HSFSC_CYCLE);
+      }
+    }
+    //
+    // If it's write cycle, load data into the SPI data buffer.
+    //
+    if ((FlashCycleType == FlashCycleWrite) || (FlashCycleType == FlashCycleWriteStatus)) {
+      if ((SpiDataCount & 0x07) != 0) {
+        //
+        // Use Byte write if Data Count is 0, 1, 2, 3, 4, 5, 6, 7
+        //
+        for (Index = 0; Index < SpiDataCount; Index++) {
+          MmioWrite8 (PchSpiBar0 + R_SPI_MEM_FDATA00 + Index, Buffer[Index]);
+        }
+      } else {
+        //
+        // Use Dword write if Data Count is 8, 16, 24, 32, 40, 48, 56, 64
+        //
+        for (Index = 0; Index < SpiDataCount; Index += sizeof (UINT32)) {
+          MmioWrite32 (PchSpiBar0 + R_SPI_MEM_FDATA00 + Index, *(UINT32 *) (Buffer + Index));
+        }
+      }
+    }
+
+    //
+    // Set the Flash Address
+    //
+    MmioWrite32 (
+      (PchSpiBar0 + R_SPI_MEM_FADDR),
+      (UINT32) (HardwareSpiAddr & B_SPI_MEM_FADDR_MASK)
+      );
+
+    //
+    // Set Data count, Flash cycle, and Set Go bit to start a cycle
+    //
+    MmioAndThenOr32 (
+      PchSpiBar0 + R_SPI_MEM_HSFSC,
+      (UINT32) (~(B_SPI_MEM_HSFSC_FDBC_MASK | B_SPI_MEM_HSFSC_CYCLE_MASK)),
+      (UINT32) ((((SpiDataCount - 1) << N_SPI_MEM_HSFSC_FDBC) & B_SPI_MEM_HSFSC_FDBC_MASK) | FlashCycle | B_SPI_MEM_HSFSC_CYCLE_FGO)
+      );
+    //
+    // end of command execution
+    //
+    // Wait the SPI cycle to complete.
+    //
+    if (!WaitForSpiCycleComplete (This, PchSpiBar0, TRUE)) {
+      ASSERT (FALSE);
+      Status = EFI_DEVICE_ERROR;
+      goto SendSpiCmdEnd;
+    }
+    //
+    // If it's read cycle, load data into the call's buffer.
+    //
+    if ((FlashCycleType == FlashCycleRead) ||
+        (FlashCycleType == FlashCycleReadSfdp) ||
+        (FlashCycleType == FlashCycleReadJedecId) ||
+        (FlashCycleType == FlashCycleReadStatus)) {
+      if ((SpiDataCount & 0x07) != 0) {
+        //
+        // Use Byte read if Data Count is 0, 1, 2, 3, 4, 5, 6, 7
+        //
+        for (Index = 0; Index < SpiDataCount; Index++) {
+          Buffer[Index] = MmioRead8 (PchSpiBar0 + R_SPI_MEM_FDATA00 + Index);
+        }
+      } else {
+        //
+        // Use Dword read if Data Count is 8, 16, 24, 32, 40, 48, 56, 64
+        //
+        for (Index = 0; Index < SpiDataCount; Index += sizeof (UINT32)) {
+          *(UINT32 *) (Buffer + Index) = MmioRead32 (PchSpiBar0 + R_SPI_MEM_FDATA00 + Index);
+        }
+      }
+    }
+
+    HardwareSpiAddr += SpiDataCount;
+    Buffer += SpiDataCount;
+    ByteCount -= SpiDataCount;
+  } while (ByteCount > 0);
+
+SendSpiCmdEnd:
+  //
+  // Restore the settings for SPI Prefetching and Caching and enable BIOS Write Protect
+  //
+  if ((FlashCycleType == FlashCycleWrite) ||
+      (FlashCycleType == FlashCycleErase)) {
+    EnableBiosWriteProtect ();
+    PciSegmentAndThenOr8 (
+      SpiBaseAddress + R_SPI_CFG_BC,
+      (UINT8) ~B_SPI_CFG_BC_SRC,
+      BiosCtlSave
+      );
+  }
+  //
+  // Restore SMIs.
+  //
+  IoWrite32 ((UINTN) (ABase + R_ACPI_IO_SMI_EN), SmiEnSave);
+
+  ReleaseSpiBar0 (SpiInstance);
+
+  return Status;
+}
+
+/**
+  Read data from the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] FlashRegionType      The Flash Region type for flash cycle which is listed in the Descriptor.
+  @param[in] Address              The Flash Linear Address must fall within a region for which BIOS has access permissions.
+  @param[in] ByteCount            Number of bytes in the data portion of the SPI cycle.
+  @param[out] Buffer              The Pointer to caller-allocated buffer containing the dada received.
+                                  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashRead (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     FLASH_REGION_TYPE  FlashRegionType,
+  IN     UINT32             Address,
+  IN     UINT32             ByteCount,
+  OUT    UINT8              *Buffer
+  )
+{
+  EFI_STATUS        Status;
+
+  //
+  // Sends the command to the SPI interface to execute.
+  //
+  Status = SendSpiCmd (
+             This,
+             FlashRegionType,
+             FlashCycleRead,
+             Address,
+             ByteCount,
+             Buffer
+             );
+  return Status;
+}
+
+/**
+  Write data to the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] FlashRegionType      The Flash Region type for flash cycle which is listed in the Descriptor.
+  @param[in] Address              The Flash Linear Address must fall within a region for which BIOS has access permissions.
+  @param[in] ByteCount            Number of bytes in the data portion of the SPI cycle.
+  @param[in] Buffer               Pointer to caller-allocated buffer containing the data sent during the SPI cycle.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashWrite (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     FLASH_REGION_TYPE  FlashRegionType,
+  IN     UINT32             Address,
+  IN     UINT32             ByteCount,
+  IN     UINT8              *Buffer
+  )
+{
+  EFI_STATUS        Status;
+
+  //
+  // Sends the command to the SPI interface to execute.
+  //
+  Status = SendSpiCmd (
+             This,
+             FlashRegionType,
+             FlashCycleWrite,
+             Address,
+             ByteCount,
+             Buffer
+             );
+  return Status;
+}
+
+/**
+  Erase some area on the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] FlashRegionType      The Flash Region type for flash cycle which is listed in the Descriptor.
+  @param[in] Address              The Flash Linear Address must fall within a region for which BIOS has access permissions.
+  @param[in] ByteCount            Number of bytes in the data portion of the SPI cycle.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashErase (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     FLASH_REGION_TYPE  FlashRegionType,
+  IN     UINT32             Address,
+  IN     UINT32             ByteCount
+  )
+{
+  EFI_STATUS        Status;
+
+  //
+  // Sends the command to the SPI interface to execute.
+  //
+  Status = SendSpiCmd (
+             This,
+             FlashRegionType,
+             FlashCycleErase,
+             Address,
+             ByteCount,
+             NULL
+             );
+  return Status;
+}
+
+/**
+  Read SFDP data from the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] ComponentNumber      The Componen Number for chip select
+  @param[in] Address              The starting byte address for SFDP data read.
+  @param[in] ByteCount            Number of bytes in SFDP data portion of the SPI cycle
+  @param[out] SfdpData            The Pointer to caller-allocated buffer containing the SFDP data received
+                                  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+  @retval EFI_UNSUPPORTED         Unsupported operation with SAF Mode enabled
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashReadSfdp (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT8              ComponentNumber,
+  IN     UINT32             Address,
+  IN     UINT32             ByteCount,
+  OUT    UINT8              *SfdpData
+  )
+{
+  SPI_INSTANCE      *SpiInstance;
+  EFI_STATUS        Status;
+  UINT32            FlashAddress;
+
+  if (SpiIsSafModeActive ()) {
+    DEBUG ((DEBUG_ERROR, "Unallowed call to %a while SAF Mode is active.\n", __FUNCTION__));
+    return EFI_UNSUPPORTED;
+  }
+
+  SpiInstance       = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+  Status            = EFI_SUCCESS;
+
+  if (ComponentNumber > SpiInstance->NumberOfComponents) {
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  FlashAddress = 0;
+  if (ComponentNumber == FlashComponent1) {
+    FlashAddress = SpiInstance->Component1StartAddr;
+  }
+  FlashAddress += Address;
+  //
+  // Sends the command to the SPI interface to execute.
+  //
+  Status = SendSpiCmd (
+             This,
+             FlashRegionAll,
+             FlashCycleReadSfdp,
+             FlashAddress,
+             ByteCount,
+             SfdpData
+             );
+  return Status;
+}
+
+/**
+  Read Jedec Id from the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] ComponentNumber      The Componen Number for chip select
+  @param[in] ByteCount            Number of bytes in JedecId data portion of the SPI cycle, the data size is 3 typically
+  @param[out] JedecId             The Pointer to caller-allocated buffer containing JEDEC ID received
+                                  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+  @retval EFI_UNSUPPORTED         Unsupported operation with SAF Mode enabled
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashReadJedecId (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT8              ComponentNumber,
+  IN     UINT32             ByteCount,
+  OUT    UINT8              *JedecId
+  )
+{
+  SPI_INSTANCE      *SpiInstance;
+  EFI_STATUS        Status;
+  UINT32            Address;
+
+  if (SpiIsSafModeActive ()) {
+    DEBUG ((DEBUG_ERROR, "Unallowed call to %a while SAF Mode is active.\n", __FUNCTION__));
+    return EFI_UNSUPPORTED;
+  }
+
+  SpiInstance       = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+  Status            = EFI_SUCCESS;
+
+  if (ComponentNumber > SpiInstance->NumberOfComponents) {
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Address = 0;
+  if (ComponentNumber == FlashComponent1) {
+    Address = SpiInstance->Component1StartAddr;
+  }
+
+  //
+  // Sends the command to the SPI interface to execute.
+  //
+  Status = SendSpiCmd (
+             This,
+             FlashRegionAll,
+             FlashCycleReadJedecId,
+             Address,
+             ByteCount,
+             JedecId
+             );
+  return Status;
+}
+
+/**
+  Write the status register in the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] ByteCount            Number of bytes in Status data portion of the SPI cycle, the data size is 1 typically
+  @param[in] StatusValue          The Pointer to caller-allocated buffer containing the value of Status register writing
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+  @retval EFI_UNSUPPORTED         Unsupported operation with SAF Mode enabled
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashWriteStatus (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT32             ByteCount,
+  IN     UINT8              *StatusValue
+  )
+{
+  EFI_STATUS        Status;
+
+  if (SpiIsSafModeActive ()) {
+    DEBUG ((DEBUG_ERROR, "Unallowed call to %a while SAF Mode is active.\n", __FUNCTION__));
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Sends the command to the SPI interface to execute.
+  //
+  Status = SendSpiCmd (
+             This,
+             FlashRegionAll,
+             FlashCycleWriteStatus,
+             0,
+             ByteCount,
+             StatusValue
+             );
+  return Status;
+}
+
+/**
+  Read status register in the flash part.
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] ByteCount            Number of bytes in Status data portion of the SPI cycle, the data size is 1 typically
+  @param[out] StatusValue         The Pointer to caller-allocated buffer containing the value of Status register received.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+  @retval EFI_UNSUPPORTED         Unsupported operation with SAF Mode enabled
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolFlashReadStatus (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT32             ByteCount,
+  OUT    UINT8              *StatusValue
+  )
+{
+  EFI_STATUS        Status;
+
+  if (SpiIsSafModeActive ()) {
+    DEBUG ((DEBUG_ERROR, "Unallowed call to %a while SAF Mode is active.\n", __FUNCTION__));
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Sends the command to the SPI interface to execute.
+  //
+  Status = SendSpiCmd (
+             This,
+             FlashRegionAll,
+             FlashCycleReadStatus,
+             0,
+             ByteCount,
+             StatusValue
+             );
+  return Status;
+}
+
+/**
+  Get the SPI region base and size, based on the enum type
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] FlashRegionType      The Flash Region type for for the base address which is listed in the Descriptor.
+  @param[out] BaseAddress         The Flash Linear Address for the Region 'n' Base
+  @param[out] RegionSize          The size for the Region 'n'
+
+  @retval EFI_SUCCESS             Read success
+  @retval EFI_INVALID_PARAMETER   Invalid region type given
+  @retval EFI_DEVICE_ERROR        The region is not used
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolGetRegionAddress (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     FLASH_REGION_TYPE  FlashRegionType,
+  OUT    UINT32             *BaseAddress,
+  OUT    UINT32             *RegionSize
+  )
+{
+  SPI_INSTANCE    *SpiInstance;
+  UINTN           PchSpiBar0;
+  UINT32          ReadValue;
+
+  SpiInstance     = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+
+  if (FlashRegionType >= FlashRegionMax) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (FlashRegionType == FlashRegionAll) {
+    *BaseAddress  = 0;
+    *RegionSize   = SpiInstance->TotalFlashSize;
+    return EFI_SUCCESS;
+  }
+
+  PchSpiBar0      = AcquireSpiBar0 (SpiInstance);
+  ReadValue = MmioRead32 (PchSpiBar0 + (R_SPI_MEM_FREG0_FLASHD + (S_SPI_MEM_FREGX * ((UINT32) FlashRegionType))));
+  ReleaseSpiBar0 (SpiInstance);
+
+  //
+  // If the region is not used, the Region Base is 7FFFh and Region Limit is 0000h
+  //
+  if (ReadValue == B_SPI_MEM_FREGX_BASE_MASK) {
+    return EFI_DEVICE_ERROR;
+  }
+  *BaseAddress = ((ReadValue & B_SPI_MEM_FREGX_BASE_MASK) >> N_SPI_MEM_FREGX_BASE) <<
+    N_SPI_MEM_FREGX_BASE_REPR;
+  //
+  // Region limit address Bits[11:0] are assumed to be FFFh
+  //
+  *RegionSize = ((((ReadValue & B_SPI_MEM_FREGX_LIMIT_MASK) >> N_SPI_MEM_FREGX_LIMIT) + 1) <<
+                 N_SPI_MEM_FREGX_LIMIT_REPR) - *BaseAddress;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Read PCH Soft Strap Values
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] SoftStrapAddr        PCH Soft Strap address offset from FPSBA.
+  @param[in] ByteCount            Number of bytes in SoftStrap data portion of the SPI cycle
+  @param[out] SoftStrapValue      The Pointer to caller-allocated buffer containing PCH Soft Strap Value.
+                                  If the value of ByteCount is 0, the data type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Soft Strap Length
+                                  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolReadPchSoftStrap (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT32             SoftStrapAddr,
+  IN     UINT32             ByteCount,
+  OUT    VOID               *SoftStrapValue
+  )
+{
+  SPI_INSTANCE      *SpiInstance;
+  UINT32            StrapFlashAddr;
+  EFI_STATUS        Status;
+
+  SpiInstance     = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+
+  if (ByteCount == 0) {
+    *(UINT16 *) SoftStrapValue = SpiInstance->PchStrapSize;
+    return EFI_SUCCESS;
+  }
+
+  if ((SoftStrapAddr + ByteCount) > (UINT32) SpiInstance->PchStrapSize) {
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // PCH Strap Flash Address = FPSBA + RamAddr
+  //
+  StrapFlashAddr = SpiInstance->PchStrapBaseAddr + SoftStrapAddr;
+
+  //
+  // Read PCH Soft straps from using execute command
+  //
+  Status = SendSpiCmd (
+             This,
+             FlashRegionDescriptor,
+             FlashCycleRead,
+             StrapFlashAddr,
+             ByteCount,
+             SoftStrapValue
+             );
+  return Status;
+}
+
+/**
+  Read CPU Soft Strap Values
+
+  @param[in] This                 Pointer to the PCH_SPI_PROTOCOL instance.
+  @param[in] SoftStrapAddr        CPU Soft Strap address offset from FCPUSBA.
+  @param[in] ByteCount            Number of bytes in SoftStrap data portion of the SPI cycle.
+  @param[out] SoftStrapValue      The Pointer to caller-allocated buffer containing CPU Soft Strap Value.
+                                  If the value of ByteCount is 0, the data type of SoftStrapValue should be UINT16 and SoftStrapValue will be PCH Soft Strap Length
+                                  It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+
+  @retval EFI_SUCCESS             Command succeed.
+  @retval EFI_INVALID_PARAMETER   The parameters specified are not valid.
+  @retval EFI_DEVICE_ERROR        Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolReadCpuSoftStrap (
+  IN     PCH_SPI_PROTOCOL   *This,
+  IN     UINT32             SoftStrapAddr,
+  IN     UINT32             ByteCount,
+  OUT    VOID               *SoftStrapValue
+  )
+{
+  SPI_INSTANCE      *SpiInstance;
+  UINT32            StrapFlashAddr;
+  EFI_STATUS        Status;
+
+  SpiInstance     = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+
+  if (ByteCount == 0) {
+    *(UINT16 *) SoftStrapValue = SpiInstance->CpuStrapSize;
+    return EFI_SUCCESS;
+  }
+
+  if ((SoftStrapAddr + ByteCount) > (UINT32) SpiInstance->CpuStrapSize) {
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // CPU Strap Flash Address = FCPUSBA + RamAddr
+  //
+  StrapFlashAddr = SpiInstance->CpuStrapBaseAddr + SoftStrapAddr;
+
+  //
+  // Read Cpu Soft straps from using execute command
+  //
+  Status = SendSpiCmd (
+             This,
+             FlashRegionDescriptor,
+             FlashCycleRead,
+             StrapFlashAddr,
+             ByteCount,
+             SoftStrapValue
+             );
+  return Status;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/PeiDxeSmmSpiAccessPrivateLib/PeiDxeSmmSpiAccessPrivateLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/PeiDxeSmmSpiAccessPrivateLib/PeiDxeSmmSpiAccessPrivateLib.inf
new file mode 100644
index 0000000000..4e059494d8
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/PeiDxeSmmSpiAccessPrivateLib/PeiDxeSmmSpiAccessPrivateLib.inf
@@ -0,0 +1,40 @@
+## @file
+# Component description file for PCH SPI access private library
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION     = 0x00010017
+BASE_NAME       = PeiDxeSmmSpiAccessPrivateLib
+FILE_GUID       = 2CD382D7-9928-C32A-601D-69797C618A6D
+VERSION_STRING  = 1.0
+MODULE_TYPE     = BASE
+LIBRARY_CLASS   = SpiAccessPrivateLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PciSegmentLib
+SpiAccessLib
+PcdLib
+S3BootScriptLib
+PchPciBdfLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+SpiAccessPrivateLib.c
+
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/PeiDxeSmmSpiAccessPrivateLib/SpiAccessPrivateLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/PeiDxeSmmSpiAccessPrivateLib/SpiAccessPrivateLib.c
new file mode 100644
index 0000000000..de1f3d3f86
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/LibraryPrivate/PeiDxeSmmSpiAccessPrivateLib/SpiAccessPrivateLib.c
@@ -0,0 +1,133 @@
+/** @file
+  SPI library for abstraction of SPI HW registers accesses
+
+  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/SpiAccessLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/DebugLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Register/SpiRegs.h>
+#include <Register/PchRegs.h>
+#include <Register/PchPcrRegs.h>
+#include <Library/PchPciBdfLib.h>
+
+/**
+  Disable EISS (Enable InSMM.STS)
+**/
+VOID
+SpiDisableEiss (
+  VOID
+  )
+{
+  UINT64  SpiBaseAddress;
+  SpiBaseAddress = SpiPciCfgBase ();
+
+  ASSERT ((PciSegmentRead8 (SpiBaseAddress + R_SPI_CFG_BC) & B_SPI_CFG_BC_LE) == 0);
+
+  PciSegmentAnd8 (SpiBaseAddress + R_SPI_CFG_BC, (UINT8) ~(B_SPI_CFG_BC_EISS));
+}
+
+/**
+  Configure BiosLockEnable bit and BiosInterfaceLock bit according to policy setting.
+
+  @param[in] BiosLockEnable     Policy for BiosLockEnable bit programming
+  @param[in] BiosInterfaceLock  Policy for BiosInterfaceLock bit programming
+
+**/
+VOID
+SpiBiosLockEnableAndBiosInterfaceLockWithS3BootScript (
+  IN BOOLEAN  BiosLockEnable,
+  IN BOOLEAN  BiosInterfaceLock
+  )
+{
+  UINT64                   SpiBaseAddress;
+  UINT8                    SpiData8;
+
+  if (!BiosLockEnable && !BiosInterfaceLock) {
+    return;
+  }
+
+  SpiBaseAddress = SpiPciCfgBase ();
+
+  ///
+  /// PCH BIOS Spec Flash Security Recommendation
+  ///
+  /// BIOS needs to enable the BIOS Lock Enable (BLE) feature of the PCH by setting
+  /// SPI/eSPI/LPC PCI offset DCh[1] = 1b.
+  /// When this bit is set, attempts to write the Write Protect Disable (WPD) bit
+  /// in PCH will cause a SMI which will allow the BIOS to verify that the write is
+  /// from a valid source.
+  /// Remember that BIOS needs to set SPI/LPC/eSPI PCI Offset DC [0] = 0b to enable
+  /// BIOS region protection before exiting the SMI handler.
+  /// Also, TCO_EN bit needs to be set (SMI_EN Register, ABASE + 30h[13] = 1b) to keep
+  /// BLE feature enabled after booting to the OS.
+  /// Intel requires that BIOS enables the Lock Enable (LE) feature of the PCH to
+  /// ensure SMM protection of flash.
+  /// RC installs a default SMI handler that clears WPD.
+  /// There could be additional SMI handler to log such attempt if desired.
+  ///
+  /// BIOS needs to enable the "Enable in SMM.STS" (EISS) feature of the PCH by setting
+  /// SPI PCI offset DCh[5] = 1b for SPI or setting eSPI PCI offset DCh[5] = 1b for eSPI.
+  /// When this bit is set, the BIOS region is not writable until SMM sets the InSMM.STS bit,
+  /// to ensure BIOS can only be modified from SMM. Please refer to CPU BWG for more details
+  /// on InSMM.STS bit.
+  /// Intel requires that BIOS enables the Lock Enable (LE) feature of the PCH to ensure
+  /// SMM protection of flash.
+  /// SPI PCI offset DCh[1] = 1b for SPI or setting eSPI PCI offset DCh[1] = 1b for eSPI.
+  /// When this bit is set, EISS is locked down.
+  ///
+  SpiData8 = 0;
+  if (BiosLockEnable) {
+    SpiData8 |= B_SPI_CFG_BC_EISS | B_SPI_CFG_BC_LE;
+  }
+  ///
+  /// BIOS also needs to set the BIOS Interface Lock Down bit in multiple locations
+  /// (PCR[DMI] + 274Ch[0], LPC/eSPI PCI offset DCh[7] and SPI PCI offset DCh[7]).
+  /// (done in PchInit/Dxe/PchInit.c by PchDmiSetBiosLockDownWithS3BootScript ()) for PCR[DMI] 274Ch)
+  /// Setting these bits will prevent writes to the Top Swap bit (under their respective locations)
+  /// and the Boot BIOS Straps. Enabling this bit will mitigate malicious software
+  /// attempts to replace the system BIOS option ROM with its own code.
+  ///
+  if (BiosInterfaceLock) {
+    SpiData8 |= B_SPI_CFG_BC_BILD;
+  }
+
+  PciSegmentOr8 (SpiBaseAddress + R_SPI_CFG_BC, SpiData8);
+  S3BootScriptSaveMemWrite (
+    S3BootScriptWidthUint8,
+    PcdGet64 (PcdPciExpressBaseAddress) + SpiBaseAddress + R_SPI_CFG_BC,
+    1,
+    (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) + SpiBaseAddress + R_SPI_CFG_BC)
+    );
+  //
+  // Reads back for posted write to take effect
+  //
+  SpiData8 = PciSegmentRead8 (SpiBaseAddress + R_SPI_CFG_BC);
+  S3BootScriptSaveMemPoll  (
+    S3BootScriptWidthUint8,
+    PcdGet64 (PcdPciExpressBaseAddress) + SpiBaseAddress + R_SPI_CFG_BC,
+    &SpiData8,
+    &SpiData8,
+    1,
+    1
+    );
+}
+
+/**
+  Clears BIOS Write Protect Disable bit
+**/
+VOID
+SpiClearBiosWriteProtectDisable (
+  VOID
+  )
+{
+  //
+  // Disable BIOSWE bit to protect BIOS
+  //
+  PciSegmentAnd8 (SpiPciCfgBase () + R_SPI_CFG_BC, (UINT8) ~B_SPI_CFG_BC_WPD);
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Smm/Spi.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Smm/Spi.c
new file mode 100644
index 0000000000..419eddaff3
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Smm/Spi.c
@@ -0,0 +1,296 @@
+/** @file
+  PCH SPI SMM Driver implements the SPI Host Controller Compatibility Interface.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Protocol/Spi.h>
+#include <Protocol/SmmCpu.h>
+#include <Library/SpiCommonLib.h>
+#include <PchReservedResources.h>
+#include <Library/SmmPchPrivateLib.h>
+#include <Library/PchPciBdfLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Register/PchRegs.h>
+#include <Register/SpiRegs.h>
+
+//
+// Global variables
+//
+GLOBAL_REMOVE_IF_UNREFERENCED SPI_INSTANCE          *mSpiInstance;
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_SMM_CPU_PROTOCOL  *mSmmCpuProtocol;
+//
+// mPchSpiResvMmioAddr keeps the reserved MMIO range assiged to SPI.
+// In SMM it always set back the reserved MMIO address to SPI BAR0 to ensure the MMIO range
+// won't overlap with SMRAM range, and trusted.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32                mSpiResvMmioAddr;
+
+/**
+  <b>SPI Runtime SMM Module Entry Point</b>\n
+  - <b>Introduction</b>\n
+    The SPI SMM module provide a standard way for other modules to use the PCH SPI Interface in SMM.
+
+  - @pre
+    - EFI_SMM_BASE2_PROTOCOL
+      - Documented in System Management Mode Core Interface Specification .
+
+  - @result
+    The SPI SMM driver produces @link _PCH_SPI_PROTOCOL PCH_SPI_PROTOCOL @endlink with GUID
+    gPchSmmSpiProtocolGuid which is different from SPI RUNTIME driver.
+
+  - <b>Integration Check List</b>\n
+    - This driver supports Descriptor Mode only.
+    - This driver supports Hardware Sequence only.
+    - When using SMM SPI Protocol to perform flash access in an SMI handler,
+      and the SMI occurrence is asynchronous to normal mode code execution,
+      proper synchronization mechanism must be applied, e.g. disable SMI before
+      the normal mode SendSpiCmd() starts and re-enable SMI after
+      the normal mode SendSpiCmd() completes.
+      @note The implementation of SendSpiCmd() uses GBL_SMI_EN in
+      SMI_EN register (ABase + 30h) to disable and enable SMIs. But this may
+      not be effective as platform may well set the SMI_LOCK bit (i.e., PMC PCI Offset A0h [4]).
+      So the synchronization at caller level is likely needed.
+
+  @param[in] ImageHandle          Image handle of this driver.
+  @param[in] SystemTable          Global system service table.
+
+  @retval EFI_SUCCESS             Initialization complete.
+  @exception EFI_UNSUPPORTED      The chipset is unsupported by this driver.
+  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to initialize the driver.
+  @retval EFI_DEVICE_ERROR        Device error, driver exits abnormally.
+**/
+EFI_STATUS
+EFIAPI
+InstallPchSpi (
+  IN EFI_HANDLE            ImageHandle,
+  IN EFI_SYSTEM_TABLE      *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  //
+  // Init PCH spi reserved MMIO address.
+  //
+  mSpiResvMmioAddr = PCH_SPI_BASE_ADDRESS;
+
+  ///
+  /// Allocate pool for SPI protocol instance
+  ///
+  Status = gSmst->SmmAllocatePool (
+                    EfiRuntimeServicesData, /// MemoryType don't care
+                    sizeof (SPI_INSTANCE),
+                    (VOID **) &mSpiInstance
+                    );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  if (mSpiInstance == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  ZeroMem ((VOID *) mSpiInstance, sizeof (SPI_INSTANCE));
+  ///
+  /// Initialize the SPI protocol instance
+  ///
+  Status = SpiProtocolConstructor (mSpiInstance);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  ///
+  /// Install the SMM PCH_SPI_PROTOCOL interface
+  ///
+  Status = gSmst->SmmInstallProtocolInterface (
+                    &(mSpiInstance->Handle),
+                    &gPchSmmSpiProtocolGuid,
+                    EFI_NATIVE_INTERFACE,
+                    &(mSpiInstance->SpiProtocol)
+                    );
+  if (EFI_ERROR (Status)) {
+    gSmst->SmmFreePool (mSpiInstance);
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Acquire PCH spi mmio address.
+  If it is ever different from the preallocated address, reassign it back.
+  In SMM, it always override the BAR0 and returns the reserved MMIO range for SPI.
+
+  @param[in] SpiInstance          Pointer to SpiInstance to initialize
+
+  @retval PchSpiBar0              return SPI MMIO address
+**/
+UINTN
+AcquireSpiBar0 (
+  IN  SPI_INSTANCE                *SpiInstance
+  )
+{
+  UINT32                          SpiBar0;
+  //
+  // Save original SPI physical MMIO address
+  //
+  SpiBar0 = PciSegmentRead32 (SpiInstance->PchSpiBase + R_SPI_CFG_BAR0) & ~(B_SPI_CFG_BAR0_MASK);
+
+  if (SpiBar0 != mSpiResvMmioAddr) {
+    //
+    // Temporary disable MSE, and override with SPI reserved MMIO address, then enable MSE.
+    //
+    PciSegmentAnd8 (SpiInstance->PchSpiBase + PCI_COMMAND_OFFSET, (UINT8) ~EFI_PCI_COMMAND_MEMORY_SPACE);
+    PciSegmentWrite32 (SpiInstance->PchSpiBase + R_SPI_CFG_BAR0, mSpiResvMmioAddr);
+    PciSegmentOr8 (SpiInstance->PchSpiBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
+  }
+  //
+  // SPIBAR0 will be different before and after PCI enum so need to get it from SPI BAR0 reg.
+  //
+  return mSpiResvMmioAddr;
+}
+
+/**
+  Release pch spi mmio address. Do nothing.
+
+  @param[in] SpiInstance          Pointer to SpiInstance to initialize
+
+  @retval None
+**/
+VOID
+ReleaseSpiBar0 (
+  IN  SPI_INSTANCE                *SpiInstance
+  )
+{
+}
+
+/**
+  This function is a hook for Spi to disable BIOS Write Protect
+
+  @retval EFI_SUCCESS             The protocol instance was properly initialized
+  @retval EFI_ACCESS_DENIED       The BIOS Region can only be updated in SMM phase
+
+**/
+EFI_STATUS
+EFIAPI
+DisableBiosWriteProtect (
+  VOID
+  )
+{
+  UINT64     SpiBaseAddress;
+
+  SpiBaseAddress = SpiPciCfgBase ();
+  // Write clear BC_SYNC_SS prior to change WPD from 0 to 1.
+  //
+  PciSegmentOr8 (
+    SpiBaseAddress + R_SPI_CFG_BC + 1,
+    (B_SPI_CFG_BC_SYNC_SS >> 8)
+    );
+  ///
+  /// Set BIOSWE bit (SPI PCI Offset DCh [0]) = 1b
+  /// Enable the access to the BIOS space for both read and write cycles
+  ///
+  PciSegmentOr8 (
+    SpiBaseAddress + R_SPI_CFG_BC,
+    B_SPI_CFG_BC_WPD
+    );
+
+  ///
+  /// PCH BIOS Spec Section 3.7 BIOS Region SMM Protection Enabling
+  /// If the following steps are implemented:
+  ///  - Set the EISS bit (SPI PCI Offset DCh [5]) = 1b
+  ///  - Follow the 1st recommendation in section 3.6
+  /// the BIOS Region can only be updated by following the steps bellow:
+  ///  - Once all threads enter SMM
+  ///  - Read memory location FED30880h OR with 00000001h, place the result in EAX,
+  ///    and write data to lower 32 bits of MSR 1FEh (sample code available)
+  ///  - Set BIOSWE bit (SPI PCI Offset DCh [0]) = 1b
+  ///  - Modify BIOS Region
+  ///  - Clear BIOSWE bit (SPI PCI Offset DCh [0]) = 0b
+  ///
+  if ((PciSegmentRead8 (SpiBaseAddress + R_SPI_CFG_BC) & B_SPI_CFG_BC_EISS) != 0) {
+    PchSetInSmmSts ();
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function is a hook for Spi to enable BIOS Write Protect
+**/
+VOID
+EFIAPI
+EnableBiosWriteProtect (
+  VOID
+  )
+{
+  UINT64     SpiBaseAddress;
+
+  SpiBaseAddress = SpiPciCfgBase ();
+  ///
+  /// Clear BIOSWE bit (SPI PCI Offset DCh [0]) = 0b
+  /// Disable the access to the BIOS space for write cycles
+  ///
+  PciSegmentAnd8 (
+    SpiBaseAddress + R_SPI_CFG_BC,
+    (UINT8) (~B_SPI_CFG_BC_WPD)
+    );
+
+  ///
+  /// Check if EISS bit is set
+  ///
+  if (((PciSegmentRead8 (SpiBaseAddress + R_SPI_CFG_BC)) & B_SPI_CFG_BC_EISS) == B_SPI_CFG_BC_EISS) {
+    PchClearInSmmSts ();
+  }
+}
+
+/**
+  Check if it's granted to do flash write.
+
+  @retval TRUE    It's secure to do flash write.
+  @retval FALSE   It's not secure to do flash write.
+**/
+BOOLEAN
+IsSpiFlashWriteGranted (
+  VOID
+  )
+{
+  EFI_STATUS    Status;
+  UINT32        CpuIndex;
+  UINT64        ProcessorId;
+
+  if (mSmmCpuProtocol == NULL) {
+    Status = gSmst->SmmLocateProtocol (&gEfiSmmCpuProtocolGuid, NULL, (VOID **)&mSmmCpuProtocol);
+    ASSERT_EFI_ERROR (Status);
+    if (mSmmCpuProtocol == NULL) {
+      return TRUE;
+    }
+  }
+
+  for (CpuIndex = 0; CpuIndex < gSmst->NumberOfCpus; CpuIndex++) {
+    Status = mSmmCpuProtocol->ReadSaveState (
+                                mSmmCpuProtocol,
+                                sizeof (ProcessorId),
+                                EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID,
+                                CpuIndex,
+                                &ProcessorId
+                                );
+    //
+    // If the processor is in SMM at the time the SMI occurred,
+    // it will return success. Otherwise, EFI_NOT_FOUND is returned.
+    //
+    if (EFI_ERROR (Status)) {
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Smm/SpiSmm.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Smm/SpiSmm.inf
new file mode 100644
index 0000000000..033134cea1
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Spi/Smm/SpiSmm.inf
@@ -0,0 +1,47 @@
+## @file
+# Component description file for the SPI SMM driver.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = SpiSmm
+FILE_GUID = 27F4917B-A707-4aad-9676-26DF168CBF0D
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_SMM_DRIVER
+PI_SPECIFICATION_VERSION = 1.10
+ENTRY_POINT = InstallPchSpi
+
+
+[LibraryClasses]
+DebugLib
+IoLib
+UefiDriverEntryPoint
+UefiBootServicesTableLib
+BaseLib
+SmmServicesTableLib
+SpiCommonLib
+SmmPchPrivateLib
+PchPciBdfLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+Spi.c
+
+
+[Protocols]
+gPchSmmSpiProtocolGuid ## PRODUCES
+gEfiSmmCpuProtocolGuid ## CONSUMES
+
+
+[Depex]
+gEfiSmmBase2ProtocolGuid AND # This is for SmmServicesTableLib
+gEfiSmmCpuProtocolGuid # This is for CpuSmmDisableBiosWriteProtect()
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 30/40] TigerlakeSiliconPkg/IpBlock: Add Vtd component
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (27 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 29/40] TigerlakeSiliconPkg/IpBlock: Add Spi component Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 31/40] TigerlakeSiliconPkg/Library: Add package common library instances Heng Luo
                   ` (9 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * IpBlock/Vtd/IncludePrivate
  * IpBlock/Vtd/Library
  * IpBlock/Vtd/LibraryPrivate

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVtdInitLib.h              |  62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVtdPolicyLib.h            |  67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/VtdDataHob.h                         |  32 ++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInfoLib/PeiDxeSmmVtdInfoLib.inf |  45 +++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInfoLib/VtdInfoLib.c            |  86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitLib.c        | 684 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitLib.inf      |  71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyLib/DxeVtdPolicyLib.c    |  90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyLib/DxeVtdPolicyLib.inf  |  35 +++++++++++++++++++++++++++++++++++
 9 files changed, 1172 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVtdInitLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVtdInitLib.h
new file mode 100644
index 0000000000..e439cfbac2
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVtdInitLib.h
@@ -0,0 +1,62 @@
+/** @file
+  Header file for DXE VTD Init Lib.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _DXE_VTD_INIT_LIB_H_
+#define _DXE_VTD_INIT_LIB_H_
+
+#include <Uefi.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/VtdInfoLib.h>
+#include <Library/SaPlatformLib.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/Pci.h>
+#include <VtdDataHob.h>
+#include <PchConfigHob.h>
+#include <PchInfoHob.h>
+#include <Register/P2sbRegs.h>
+#include <Register/IpuRegs.h>
+#include <Register/IgdRegs.h>
+#include <Register/VtdRegs.h>
+#include <DmaRemappingTable.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+#include <Protocol/AcpiTable.h>
+#include <Protocol/SaPolicy.h>
+#include <Protocol/SaNvsArea.h>
+#include <Protocol/FirmwareVolume2.h>
+
+/**
+  Locate the VT-d ACPI tables data file and read ACPI SSDT tables.
+  Publish the appropriate SSDT based on current configuration and capabilities.
+
+  @param[in] SaPolicy            SA DXE Policy protocol
+
+  @retval EFI_SUCCESS - Vtd initialization complete
+  @retval Other       - No Vtd function initiated
+**/
+EFI_STATUS
+VtdInit (
+  IN  SA_POLICY_PROTOCOL    *SaPolicy
+  );
+
+/**
+  EndOfPcieEnum routine for update DMAR
+**/
+VOID
+UpdateDmarEndOfPcieEnum (
+  VOID
+  );
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVtdPolicyLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVtdPolicyLib.h
new file mode 100644
index 0000000000..d55cf6bc34
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVtdPolicyLib.h
@@ -0,0 +1,67 @@
+/** @file
+  Prototype of the DXE VTD Policy Init library.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _DXE_VTD_POLICY_INIT_LIB_H_
+#define _DXE_VTD_POLICY_INIT_LIB_H_
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Protocol/SaPolicy.h>
+#include <ConfigBlock.h>
+#include <VtdConfig.h>
+#include <Library/SiConfigBlockLib.h>
+
+extern EFI_GUID gVtdDxeConfigGuid;
+
+/**
+  This function Load default Vtd DXE policy.
+
+  @param[in] ConfigBlockPointer    The pointer to add VTD config block
+**/
+VOID
+VtdLoadDefaultDxe (
+  IN VOID    *ConfigBlockPointer
+  );
+
+/**
+  This function prints the DXE phase VTD policy.
+
+  @param[in] SaPolicy - Instance of SA_POLICY_PROTOCOL
+**/
+VOID
+VtdPrintPolicyDxe (
+  IN  SA_POLICY_PROTOCOL      *SaPolicy
+  );
+
+/**
+  This function is used to add VTD Config Block.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add VTD config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+VtdAddConfigBlocksDxe (
+  IN VOID           *ConfigBlockTableAddress
+  );
+
+/**
+  Get VTD DXE config block table total size.
+
+  @retval     Size of VTD DXE config block table
+**/
+UINT16
+EFIAPI
+VtdGetConfigBlockTotalSizeDxe (
+  VOID
+  );
+#endif // _DXE_VTD_POLICY_INIT_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/VtdDataHob.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/VtdDataHob.h
new file mode 100644
index 0000000000..0f9d500af9
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/VtdDataHob.h
@@ -0,0 +1,32 @@
+/** @file
+  The GUID definition for Vtd Data Hob
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _VTD_DATA_HOB_H_
+#define _VTD_DATA_HOB_H_
+
+#include <Library/VtdInfoLib.h>
+#include <Base.h>
+
+extern EFI_GUID gVtdDataHobGuid;
+
+#pragma pack (push,1)
+
+///
+/// The data elements should be initialized by a Platform Module.
+/// The data structure is for VT-d driver initialization
+///
+typedef struct {
+  EFI_HOB_GUID_TYPE     EfiHobGuidType;                    ///< GUID Hob type structure for gVtdDataHobGuid
+  BOOLEAN               VtdDisable;                        ///< 1 = Avoids programming Vtd bars, Vtd overrides and DMAR table
+  UINT32                BaseAddress[VTD_ENGINE_NUMBER];    ///< This field is used to describe the base addresses for VT-d function
+  BOOLEAN               X2ApicOptOut;                      ///< This field is used to enable the X2APIC_OPT_OUT bit in the DMAR table. <b>1=Enable/Set</b> and 0=Disable/Clear
+  BOOLEAN               DmaControlGuarantee;               ///< This field is used to enable the DMA_CONTROL_GUARANTEE bit in the DMAR table. <b>1=Enable/Set</b> and 0=Disable/Clear
+  BOOLEAN               InterruptRemappingSupport;         ///< This field is used to indicate Interrupt Remapping supported or not
+  UINT32                DmaBufferBase;                     ///< Iommu PEI DMA buffer base in low memory region, in Mbytes units
+} VTD_DATA_HOB;
+
+#pragma pack (pop)
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInfoLib/PeiDxeSmmVtdInfoLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInfoLib/PeiDxeSmmVtdInfoLib.inf
new file mode 100644
index 0000000000..c7c5e56b84
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInfoLib/PeiDxeSmmVtdInfoLib.inf
@@ -0,0 +1,45 @@
+## @file
+# VTD Common Library.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmVtdInfoLib
+FILE_GUID = A1480873-3FDA-4E90-B450-743D8031F9DE
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = VtdInfoLib
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PciSegmentLib
+HobLib
+VtdInfoLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Sources]
+VtdInfoLib.c
+
+[Pcd]
+gSiPkgTokenSpaceGuid.VtdEngine1BaseAddeess
+gSiPkgTokenSpaceGuid.VtdEngine2BaseAddeess
+gSiPkgTokenSpaceGuid.VtdEngine3BaseAddeess
+gSiPkgTokenSpaceGuid.VtdEngine4BaseAddeess
+gSiPkgTokenSpaceGuid.VtdEngine5BaseAddeess
+gSiPkgTokenSpaceGuid.VtdEngine6BaseAddeess
+gSiPkgTokenSpaceGuid.VtdEngine7BaseAddeess
+
+[FixedPcd]
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInfoLib/VtdInfoLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInfoLib/VtdInfoLib.c
new file mode 100644
index 0000000000..e4f08592cc
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInfoLib/VtdInfoLib.c
@@ -0,0 +1,86 @@
+/** @file
+  VTD Info library.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Ppi/SiPolicy.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/VtdInfoLib.h>
+#include <Register/VtdRegs.h>
+
+/**
+  Get VTD Engine Base Address from PCD value
+
+  @param[in]  VtdEngineNumber        - Engine number for which VTD Base Adderess is required.
+
+  @retval   VTD Engine Base Address
+**/
+UINT32
+GetVtdBaseAddress (
+  IN UINT8        VtdEngineNumber
+  )
+{
+  switch (VtdEngineNumber) {
+    case 0:
+      return PcdGet32(VtdEngine1BaseAddeess);
+      break;
+    case 2:
+      return PcdGet32(VtdEngine3BaseAddeess);
+      break;
+    default:
+      return 0x0;
+      break;
+  }
+}
+
+
+/**
+  Read VTD Engine Base Address from VTD BAR Offsets.
+
+  @param[in]  VtdEngineNumber        - Engine number for which VTD Base Adderess is required.
+
+  @retval   VTD Engine Base Address
+**/
+UINT32
+ReadVtdBaseAddress (
+  IN UINT8        VtdEngineNumber
+  )
+{
+  UINT64              McD0BaseAddress;
+  UINTN               MchBar;
+
+  McD0BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, 0);
+  MchBar          = PciSegmentRead32 (McD0BaseAddress + R_SA_MCHBAR) & (~BIT0);
+
+  switch (VtdEngineNumber) {
+    case 0:
+      return (MmioRead32 (MchBar + R_MCHBAR_VTD1_OFFSET) & (~BIT0));
+      break;
+    case 2:
+      return (MmioRead32 (MchBar + R_MCHBAR_VTD3_OFFSET) & (~BIT0));
+      break;
+    default:
+      return 0x0;
+      break;
+  }
+}
+
+/**
+  GetMaxVtdEngineNumber: Get Maximum Vtd Engine Number
+
+  @retval Vtd Engine Number
+**/
+UINT8
+GetMaxVtdEngineNumber(
+  VOID
+)
+{
+  return (UINT8)VTD_ENGINE_NUMBER;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitLib.c
new file mode 100644
index 0000000000..faac07c45d
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitLib.c
@@ -0,0 +1,684 @@
+/** @file
+  DXE Library for VTD ACPI table initialization.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Library/DxeVtdInitLib.h>
+#include <Library/DxeVtdPolicyLib.h>
+#include <Library/VtdInitFruLib.h>
+#include <Register/SaRegsHostBridge.h>
+
+///
+/// Global Variables
+///
+GLOBAL_REMOVE_IF_UNREFERENCED VTD_DATA_HOB     *mVtdDataHob;
+
+BOOLEAN mInterruptRemappingSupport;
+
+/**
+  Get the corresponding device Enable/Disable bit according DevNum and FunNum
+
+  @param[in] DevNum  - Device Number
+  @param[in] FunNum  - Function Number
+
+  @retval If the device is found, return disable/Enable bit in FD/Deven reigster
+  @retval If not found return 0xFF
+**/
+UINT16
+GetFunDisableBit (
+  UINT8 DevNum,
+  UINT8 FunNum
+  )
+{
+  UINTN Index;
+
+  for (Index = 0; Index < mDevEnMapSize; Index++) {
+    if (mDevEnMap[Index][0] == ((DevNum << 0x08) | FunNum)) {
+      return mDevEnMap[Index][1];
+    }
+  }
+
+  return 0xFF;
+}
+
+/**
+  Update the DRHD structure
+
+  @param[in, out] DrhdEnginePtr       - A pointer to DRHD structure
+**/
+VOID
+UpdateDrhd (
+  IN OUT VOID *DrhdEnginePtr
+  )
+{
+  UINT16                        Length;
+  UINT16                        DisableBit;
+  BOOLEAN                       NeedRemove;
+  EFI_ACPI_DRHD_ENGINE1_STRUCT  *DrhdEngine;
+
+  //
+  // Convert DrhdEnginePtr to EFI_ACPI_DRHD_ENGINE1_STRUCT Pointer
+  //
+  DrhdEngine      = (EFI_ACPI_DRHD_ENGINE1_STRUCT *) DrhdEnginePtr;
+  Length          = DrhdEngine->DrhdHeader.Header.Length;
+  DisableBit = GetFunDisableBit (
+                 DrhdEngine->DeviceScope[0].PciPath.Device,
+                 DrhdEngine->DeviceScope[0].PciPath.Function
+                 );
+  NeedRemove = FALSE;
+
+  if ((DisableBit == 0xFF) ||
+      (DrhdEngine->DrhdHeader.RegisterBaseAddress == 0) ||
+      ((DisableBit == 0x80) &&
+       (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0, DrhdEngine->DeviceScope[0].PciPath.Device, DrhdEngine->DeviceScope[0].PciPath.Function, 0x00)) == 0xFFFFFFFF))
+      ) {
+    NeedRemove = TRUE;
+  }
+  if ((DrhdEngine->DeviceScope[0].PciPath.Device == IGD_DEV_NUM) && (DrhdEngine->DeviceScope[0].PciPath.Function == IGD_FUN_NUM) &&
+      (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0, DrhdEngine->DeviceScope[0].PciPath.Device, DrhdEngine->DeviceScope[0].PciPath.Function, 0x00)) != 0xFFFFFFFF)) {
+    NeedRemove = FALSE;
+  }
+  if (NeedRemove) {
+    Length -= sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
+  }
+  ///
+  /// If no devicescope is left, we set the structure length as 0x00
+  ///
+  if ((Length > EFI_ACPI_DRHD_ENGINE_HEADER_LENGTH) || (DrhdEngine->DrhdHeader.Flags == 0x01)) {
+    DrhdEngine->DrhdHeader.Header.Length = Length;
+  } else {
+    DrhdEngine->DrhdHeader.Header.Length = 0;
+  }
+}
+
+/**
+  Get IOAPIC ID from LPC
+
+  @retval APIC ID
+**/
+UINT8
+GetIoApicId (
+  VOID
+  )
+{
+  UINT32                IoApicAddress;
+  UINT32                IoApicId;
+
+  IoApicAddress = PcdGet32 (PcdSiIoApicBaseAddress);
+  ///
+  /// Get current IO APIC ID
+  ///
+  MmioWrite8 ((UINTN) (IoApicAddress + R_IO_APIC_MEM_INDEX_OFFSET), 0);
+  IoApicId = MmioRead32 ((UINTN) (IoApicAddress + R_IO_APIC_MEM_DATA_OFFSET)) >> 24;
+
+  return (UINT8) IoApicId;
+}
+
+/**
+  Update the second DRHD structure
+
+  @param[in, out] DrhdEnginePtr       - A pointer to DRHD structure
+**/
+VOID
+UpdateDrhd2 (
+  IN OUT VOID *DrhdEnginePtr
+  )
+{
+  UINT16                        Length;
+  UINTN                         DeviceScopeNum;
+  UINTN                         ValidDeviceScopeNum;
+  UINT16                        Index;
+  UINT8                         Bus;
+  UINT8                         Path[2];
+  BOOLEAN                       NeedRemove;
+  EFI_ACPI_DRHD_ENGINE3_STRUCT  *DrhdEngine;
+  VOID                          *HobPtr;
+  PCH_INFO_HOB                  *PchInfoHob;
+
+  ///
+  /// Convert DrhdEnginePtr to EFI_ACPI_DRHD_ENGINE3_STRUCT Pointer
+  ///
+  DrhdEngine      = (EFI_ACPI_DRHD_ENGINE3_STRUCT *) DrhdEnginePtr;
+
+  Length          = DrhdEngine->DrhdHeader.Header.Length;
+  DeviceScopeNum  = (DrhdEngine->DrhdHeader.Header.Length - EFI_ACPI_DRHD_ENGINE_HEADER_LENGTH) / sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
+  Bus             = 0;
+  ValidDeviceScopeNum = 0;
+  Path[0]         = 0;
+  Path[1]         = 0;
+
+  HobPtr = GetFirstGuidHob (&gPchInfoHobGuid);
+  ASSERT (HobPtr != NULL);
+  if (HobPtr == NULL) {
+    return;
+  }
+  PchInfoHob = (PCH_INFO_HOB *) GET_GUID_HOB_DATA (HobPtr);
+  ASSERT (PchInfoHob != NULL);
+  if (PchInfoHob == NULL) {
+    return;
+  }
+
+  for (Index = 0; Index < DeviceScopeNum; Index++) {
+    NeedRemove = FALSE;
+    /**
+      For HPET and APIC, update device scope if Interrupt remapping is supported. remove device scope
+      if interrupt remapping is not supported.
+      - Index = 0 - IOAPIC
+      - Index = 1 - HPET
+    **/
+    if (mInterruptRemappingSupport) {
+      if (Index == 0) {
+        ///
+        /// Update source id for IoApic's device scope entry
+        ///
+        Bus = (UINT8) PchInfoHob->IoApicBusNum;
+        Path[0] = (UINT8) PchInfoHob->IoApicDevNum;
+        Path[1] = (UINT8) PchInfoHob->IoApicFuncNum;
+        DrhdEngine->DeviceScope[Index].DeviceScopeStructureHeader.StartBusNumber = Bus;
+        DrhdEngine->DeviceScope[Index].PciPath.Device = Path[0];
+        DrhdEngine->DeviceScope[Index].PciPath.Function = Path[1];
+        //
+        // Update APIC ID
+        //
+        DrhdEngine->DeviceScope[Index].DeviceScopeStructureHeader.EnumerationId = GetIoApicId ();
+      }
+      if (Index == 1) {
+        ///
+        /// Update source id for HPET's device scope entry
+        ///
+        Bus     = (UINT8) PchInfoHob->HpetBusNum;
+        Path[0] = (UINT8) PchInfoHob->HpetDevNum;
+        Path[1] = (UINT8) PchInfoHob->HpetFuncNum;
+        DrhdEngine->DeviceScope[Index].DeviceScopeStructureHeader.StartBusNumber = Bus;
+        DrhdEngine->DeviceScope[Index].PciPath.Device = Path[0];
+        DrhdEngine->DeviceScope[Index].PciPath.Function = Path[1];
+      }
+    } else {
+      if ((Index == 0) || (Index == 1)) {
+        NeedRemove = TRUE;
+      }
+    }
+
+    CopyMem (
+      &DrhdEngine->DeviceScope[ValidDeviceScopeNum],
+      &DrhdEngine->DeviceScope[Index],
+      sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE)
+      );
+    if (NeedRemove) {
+      Length -= sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
+    } else {
+      ValidDeviceScopeNum++;
+    }
+  }
+  ///
+  /// If no devicescope is left, we set the structure length as 0x00
+  ///
+  if ((Length > EFI_ACPI_DRHD_ENGINE_HEADER_LENGTH) || (DrhdEngine->DrhdHeader.Flags == 0x01)) {
+    DrhdEngine->DrhdHeader.Header.Length = Length;
+  } else {
+    DrhdEngine->DrhdHeader.Header.Length = 0;
+  }
+}
+
+/**
+  Update the RMRR structure
+
+  @param[in, out] RmrrPtr             - A pointer to RMRR structure
+**/
+VOID
+UpdateRmrr (
+  IN OUT VOID *RmrrPtr
+  )
+{
+  UINT16                  Length;
+  UINT16                  DisableBit;
+  UINTN                   DeviceScopeNum;
+  UINTN                   ValidDeviceScopeNum;
+  UINTN                   Index;
+  BOOLEAN                 NeedRemove;
+  EFI_ACPI_RMRR_USB_STRUC *Rmrr;
+
+  ///
+  /// To make sure all devicescope can be checked,
+  /// we convert the RmrrPtr to EFI_ACPI_RMRR_USB_STRUC pointer
+  ///
+  Rmrr                = (EFI_ACPI_RMRR_USB_STRUC *) RmrrPtr;
+
+  Length              = Rmrr->RmrrHeader.Header.Length;
+  ValidDeviceScopeNum = 0;
+  DeviceScopeNum      = (Rmrr->RmrrHeader.Header.Length - EFI_ACPI_RMRR_HEADER_LENGTH) / sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
+  for (Index = 0; Index < DeviceScopeNum; Index++) {
+    DisableBit = GetFunDisableBit (
+                   Rmrr->DeviceScope[Index].PciPath.Device,
+                   Rmrr->DeviceScope[Index].PciPath.Function
+                   );
+    NeedRemove = FALSE;
+    if ((DisableBit == 0xFF) ||
+        ((DisableBit == 0x80) &&
+         (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0, Rmrr->DeviceScope[Index].PciPath.Device, Rmrr->DeviceScope[Index].PciPath.Function, 0x00)) == 0xFFFFFFFF))
+        ) {
+      NeedRemove = TRUE;
+    } else if (DisableBit == 0x8F) {
+      DEBUG ((DEBUG_ERROR, "Rmrr->RmrrHeader.ReservedMemoryRegionBaseAddress %x\n", Rmrr->RmrrHeader.ReservedMemoryRegionBaseAddress));
+
+      if (Rmrr->RmrrHeader.ReservedMemoryRegionBaseAddress != 0) {
+        DEBUG ((DEBUG_ERROR, "NeedRemove = FALSE\n"));
+        NeedRemove = FALSE;
+      } else {
+        DEBUG ((DEBUG_ERROR, "NeedRemove = TRUE\n"));
+        NeedRemove = TRUE;
+      }
+    }
+    CopyMem (
+      &Rmrr->DeviceScope[ValidDeviceScopeNum],
+      &Rmrr->DeviceScope[Index],
+      sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE)
+      );
+
+    if (Rmrr->RmrrHeader.ReservedMemoryRegionLimitAddress == 0x0) {
+      NeedRemove = TRUE;
+    }
+
+    if (NeedRemove) {
+      Length -= sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
+    } else {
+      ValidDeviceScopeNum++;
+    }
+  }
+  ///
+  /// If No deviceScope is left, set length as 0x00
+  ///
+  if (Length > EFI_ACPI_RMRR_HEADER_LENGTH) {
+    Rmrr->RmrrHeader.Header.Length = Length;
+  } else {
+    Rmrr->RmrrHeader.Header.Length = 0;
+  }
+}
+
+/**
+  Update the DMAR table
+
+  @param[in, out] TableHeader         - The table to be set
+  @param[in, out] Version             - Version to publish
+**/
+VOID
+DmarTableUpdate (
+  IN OUT   EFI_ACPI_DESCRIPTION_HEADER       *TableHeader,
+  IN OUT   EFI_ACPI_TABLE_VERSION            *Version
+  )
+{
+  EFI_ACPI_DMAR_TABLE *DmarTable;
+  EFI_ACPI_DMAR_TABLE TempDmarTable;
+  UINTN               Offset;
+  UINTN               StructureLen;
+  UINT64              McD0BaseAddress;
+  UINT32              GttMmAdr;
+  UINT64              McD2BaseAddress;
+  UINT16              IgdMode;
+  UINT16              GttMode;
+  UINT32              IgdMemSize;
+  UINT32              GttMemSize;
+  EFI_STATUS          Status;
+  VTD_DXE_CONFIG      *VtdDxeConfig;
+  SA_POLICY_PROTOCOL  *SaPolicy;
+
+
+  IgdMemSize  = 0;
+  GttMemSize  = 0;
+  DmarTable   = (EFI_ACPI_DMAR_TABLE *) TableHeader;
+
+  Status = gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID **) &SaPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gVtdDxeConfigGuid, (VOID *)&VtdDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Set INTR_REMAP bit (BIT 0) if interrupt remapping is supported
+  ///
+  if (mInterruptRemappingSupport) {
+    DmarTable->DmarHeader.Flags |= BIT0;
+  }
+
+  if (mVtdDataHob->X2ApicOptOut == 1) {
+    DmarTable->DmarHeader.Flags |= BIT1;
+  } else {
+    DmarTable->DmarHeader.Flags &= 0xFD;
+  }
+
+  ///
+  /// Set DMA_CONTROL_GUARANTEE bit (BIT 2) if Dma Control Guarantee is supported
+  ///
+  if (mVtdDataHob->DmaControlGuarantee == 1) {
+    DmarTable->DmarHeader.Flags |= BIT2;
+  }
+  ///
+  /// Get OemId
+  ///
+  CopyMem (DmarTable->DmarHeader.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (DmarTable->DmarHeader.Header.OemId));
+  DmarTable->DmarHeader.Header.OemTableId      = PcdGet64 (PcdAcpiDefaultOemTableId);
+  DmarTable->DmarHeader.Header.OemRevision     = PcdGet32 (PcdAcpiDefaultOemRevision);
+  DmarTable->DmarHeader.Header.CreatorId       = PcdGet32 (PcdAcpiDefaultCreatorId);
+  DmarTable->DmarHeader.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
+
+  ///
+  /// Calculate IGD memsize
+  ///
+  McD0BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, 0);
+  IgdMode = ((PciSegmentRead16 (McD0BaseAddress + R_SA_GGC) & B_SA_GGC_GMS_MASK) >> N_SA_GGC_GMS_OFFSET) & 0xFF;
+  if (IgdMode < 0xF0) {
+    IgdMemSize = IgdMode * 32 * (1024) * (1024);
+  } else {
+    IgdMemSize = 4 * (IgdMode - 0xF0 + 1) * (1024) * (1024);
+  }
+  ///
+  /// Calculate GTT mem size
+  ///
+  GttMemSize = 0;
+  GttMode = (PciSegmentRead16 (McD0BaseAddress + R_SA_GGC) & B_SA_GGC_GGMS_MASK) >> N_SA_GGC_GGMS_OFFSET;
+  if (GttMode <= V_SA_GGC_GGMS_8MB) {
+    GttMemSize = (1 << GttMode) * (1024) * (1024);
+  }
+
+  McD2BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, IGD_BUS_NUM, IGD_DEV_NUM, IGD_FUN_NUM, 0);
+  GttMmAdr = (PciSegmentRead32 (McD2BaseAddress + R_SA_IGD_GTTMMADR)) & 0xFFFFFFF0;
+
+  DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress   = (PciSegmentRead32 (McD0BaseAddress + R_SA_BGSM) & ~(0x01));
+  DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionLimitAddress  = DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress + IgdMemSize + GttMemSize - 1;
+  DEBUG ((DEBUG_INFO, "RMRR Base  address IGD %016lX\n", DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress));
+  DEBUG ((DEBUG_INFO, "RMRR Limit address IGD %016lX\n", DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionLimitAddress));
+
+  ///
+  /// Update DRHD structures of DmarTable
+  ///
+  DmarTable->DrhdEngine1.DrhdHeader.RegisterBaseAddress = ReadVtdBaseAddress(0);
+  DmarTable->DrhdEngine3.DrhdHeader.RegisterBaseAddress = ReadVtdBaseAddress (2);
+
+  DEBUG ((DEBUG_INFO, "VTD base address 1 = %x\n", DmarTable->DrhdEngine1.DrhdHeader.RegisterBaseAddress));
+  DEBUG ((DEBUG_INFO, "VTD base address 3 = %x\n", DmarTable->DrhdEngine3.DrhdHeader.RegisterBaseAddress));
+  ///
+  /// copy DmarTable to TempDmarTable to be processed
+  ///
+  CopyMem (&TempDmarTable, DmarTable, sizeof (EFI_ACPI_DMAR_TABLE));
+
+  ///
+  /// Update DRHD structures of temp DMAR table
+  ///
+  UpdateDrhd (&TempDmarTable.DrhdEngine1);
+  UpdateDrhd2 (&TempDmarTable.DrhdEngine3);
+
+  ///
+  /// Remove unused device scope or entire DRHD structures
+  ///
+  Offset = (UINTN) (&TempDmarTable.DrhdEngine1);
+  if (TempDmarTable.DrhdEngine1.DrhdHeader.Header.Length != 0) {
+    Offset += TempDmarTable.DrhdEngine1.DrhdHeader.Header.Length;
+  }
+  if (TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length != 0) {
+    StructureLen = TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length;
+    CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.DrhdEngine3, TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length);
+    Offset += StructureLen;
+  }
+  ///
+  /// Remove unused device scope or entire RMRR structures
+  ///
+  if (TempDmarTable.RmrrIgd.RmrrHeader.Header.Length != 0) {
+    StructureLen = TempDmarTable.RmrrIgd.RmrrHeader.Header.Length;
+    CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.RmrrIgd, TempDmarTable.RmrrIgd.RmrrHeader.Header.Length);
+    Offset += StructureLen;
+  }
+  Offset = Offset - (UINTN) &TempDmarTable;
+  ///
+  /// Re-calculate DMAR table check sum
+  ///
+  TempDmarTable.DmarHeader.Header.Checksum = (UINT8) (TempDmarTable.DmarHeader.Header.Checksum + TempDmarTable.DmarHeader.Header.Length - Offset);
+  ///
+  /// Set DMAR table length
+  ///
+  TempDmarTable.DmarHeader.Header.Length = (UINT32) Offset;
+  ///
+  /// Replace DMAR table with rebuilt table TempDmarTable
+  ///
+  CopyMem ((VOID *) DmarTable, (VOID *) &TempDmarTable, TempDmarTable.DmarHeader.Header.Length);
+}
+
+/**
+  EndOfPcieEnumration routine for update DMAR
+**/
+VOID
+UpdateDmarEndOfPcieEnum (
+  VOID
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_HANDLE                      *HandleBuffer;
+  UINTN                           NumberOfHandles;
+  EFI_FV_FILETYPE                 FileType;
+  UINT32                          FvStatus;
+  EFI_FV_FILE_ATTRIBUTES          Attributes;
+  UINTN                           Size;
+  UINTN                           i;
+  INTN                            Instance;
+  EFI_ACPI_TABLE_VERSION          Version;
+  EFI_ACPI_COMMON_HEADER          *CurrentTable;
+  UINTN                           AcpiTableHandle;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL   *FwVol;
+  EFI_ACPI_TABLE_PROTOCOL         *AcpiTable;
+  EFI_ACPI_DESCRIPTION_HEADER     *VtdAcpiTable;
+  STATIC BOOLEAN                  Triggered = FALSE;
+
+
+  if (Triggered) {
+    return;
+  }
+
+  Triggered     = TRUE;
+
+  FwVol         = NULL;
+  AcpiTable     = NULL;
+  VtdAcpiTable  = NULL;
+
+  DEBUG ((DEBUG_INFO, "UpdateDmarEndOfPcieEnum \n"));
+
+
+  ///
+  /// Fix DMAR Table always created, skip install when disabled
+  ///
+  if ((mVtdDataHob->VtdDisable == TRUE) || (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, R_SA_MC_CAPID0_A_OFFSET)) & BIT23)) {
+    DEBUG ((DEBUG_INFO, "Vtd Disabled, skip DMAR Table install\n"));
+    return;
+  }
+
+
+  ///
+  /// Locate ACPI support protocol
+  ///
+  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);
+
+  ///
+  /// Locate protocol.
+  /// There is little chance we can't find an FV protocol
+  ///
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiFirmwareVolume2ProtocolGuid,
+                  NULL,
+                  &NumberOfHandles,
+                  &HandleBuffer
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Looking for FV with ACPI storage file
+  ///
+  for (i = 0; i < NumberOfHandles; i++) {
+    ///
+    /// Get the protocol on this handle
+    /// This should not fail because of LocateHandleBuffer
+    ///
+    Status = gBS->HandleProtocol (
+                    HandleBuffer[i],
+                    &gEfiFirmwareVolume2ProtocolGuid,
+                    (VOID **) &FwVol
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    ///
+    /// See if it has the ACPI storage file
+    ///
+    Size      = 0;
+    FvStatus  = 0;
+    Status = FwVol->ReadFile (
+                      FwVol,
+                      &gSaAcpiTableStorageGuid,
+                      NULL,
+                      &Size,
+                      &FileType,
+                      &Attributes,
+                      &FvStatus
+                      );
+
+    ///
+    /// If we found it, then we are done
+    ///
+    if (Status == EFI_SUCCESS) {
+      break;
+    }
+  }
+  ///
+  /// Our exit status is determined by the success of the previous operations
+  /// If the protocol was found, Instance already points to it.
+  ///
+  ///
+  /// Free any allocated buffers
+  ///
+  FreePool (HandleBuffer);
+
+  ///
+  /// Sanity check that we found our data file
+  ///
+  ASSERT (FwVol);
+  if (FwVol == NULL) {
+    return;
+  }
+  ///
+  /// By default, a table belongs in all ACPI table versions published.
+  ///
+  Version = EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0;
+
+  ///
+  /// Read tables from the storage file.
+  ///
+  Instance      = 0;
+  CurrentTable  = NULL;
+
+  while (Status == EFI_SUCCESS) {
+    Status = FwVol->ReadSection (
+                      FwVol,
+                      &gSaAcpiTableStorageGuid,
+                      EFI_SECTION_RAW,
+                      Instance,
+                      (VOID **) &CurrentTable,
+                      &Size,
+                      &FvStatus
+                      );
+
+    if (!EFI_ERROR (Status)) {
+      ///
+      /// Check the Signature ID to modify the table
+      ///
+      if ((CurrentTable != NULL) && ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Signature == EFI_ACPI_VTD_DMAR_TABLE_SIGNATURE) {
+        VtdAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
+        DmarTableUpdate (VtdAcpiTable, &Version);
+        break;
+      }
+      ///
+      /// Increment the instance
+      ///
+      Instance++;
+      if (CurrentTable != NULL) {
+        gBS->FreePool (CurrentTable);
+        CurrentTable = NULL;
+      }
+    }
+  }
+  ///
+  /// Update the VTD table in the ACPI tables.
+  ///
+  AcpiTableHandle = 0;
+  if (VtdAcpiTable != NULL) {
+    Status = AcpiTable->InstallAcpiTable (
+                          AcpiTable,
+                          VtdAcpiTable,
+                          VtdAcpiTable->Length,
+                          &AcpiTableHandle
+                          );
+    FreePool (VtdAcpiTable);
+  }
+}
+
+/**
+  Locate the VT-d ACPI tables data file and read ACPI SSDT tables.
+  Publish the appropriate SSDT based on current configuration and capabilities.
+
+  @param[in] SaPolicy     -  SA DXE Policy protocol
+
+  @retval EFI_SUCCESS     - Vtd initialization complete
+  @exception EFI_UNSUPPORTED - Vtd is not enabled by policy
+**/
+EFI_STATUS
+VtdInit (
+  IN  SA_POLICY_PROTOCOL    *SaPolicy
+  )
+{
+  EFI_STATUS                      Status;
+  UINT64                          McD0BaseAddress;
+  UINT64                          McD2BaseAddress;
+  SYSTEM_AGENT_NVS_AREA_PROTOCOL  *SaNvsAreaProtocol;
+  UINT8                           Index;
+
+  mInterruptRemappingSupport  = FALSE;
+  mVtdDataHob = NULL;
+  mVtdDataHob = GetFirstGuidHob(&gVtdDataHobGuid);
+  if (mVtdDataHob != NULL) {
+    mInterruptRemappingSupport = mVtdDataHob->InterruptRemappingSupport;
+  }
+
+  ///
+  ///  Locate the SA Global NVS Protocol.
+  ///
+  Status = gBS->LocateProtocol (
+                  &gSaNvsAreaProtocolGuid,
+                  NULL,
+                  (VOID **) &SaNvsAreaProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  McD0BaseAddress  = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, 0);
+  McD2BaseAddress  = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, IGD_BUS_NUM, IGD_DEV_NUM, IGD_FUN_NUM, 0);
+
+  if (mVtdDataHob != NULL) {
+    SaNvsAreaProtocol->Area->VtdDisable = mVtdDataHob->VtdDisable;
+  }
+
+  for (Index = 0; Index < VTD_ENGINE_NUMBER; Index++) {
+    SaNvsAreaProtocol->Area->VtdBaseAddress[Index] = ReadVtdBaseAddress (Index);
+  }
+  SaNvsAreaProtocol->Area->VtdEngine1Vid = PciSegmentRead16(McD2BaseAddress + PCI_VENDOR_ID_OFFSET);
+
+  if (mVtdDataHob != NULL) {
+    if ((mVtdDataHob->VtdDisable) || (PciSegmentRead32 (McD0BaseAddress + R_SA_MC_CAPID0_A_OFFSET) & BIT23)) {
+      DEBUG ((DEBUG_WARN, "VTd disabled or no capability!\n"));
+      return EFI_UNSUPPORTED;
+    }
+  }
+  ///
+  /// Check SA supports VTD and VTD is enabled in setup menu
+  ///
+  DEBUG ((DEBUG_INFO, "VTd enabled\n"));
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitLib.inf
new file mode 100644
index 0000000000..9797c31cc6
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitLib.inf
@@ -0,0 +1,71 @@
+## @file
+# Component description file for the Dxe VTD Init library.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeVtdInitLib
+FILE_GUID = 9BD11E68-923C-424C-A278-716084B4C931
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_DRIVER
+LIBRARY_CLASS = DxeVtdInitLib
+
+[LibraryClasses]
+UefiLib
+UefiRuntimeServicesTableLib
+UefiBootServicesTableLib
+DebugLib
+PostCodeLib
+ConfigBlockLib
+HobLib
+IoLib
+PciSegmentLib
+BaseMemoryLib
+MemoryAllocationLib
+MmPciLib
+VtdInfoLib
+PchInfoLib
+PchCycleDecodingLib
+SaPlatformLib
+DxeVtdInitFruLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Sources]
+DxeVtdInitLib.c
+
+[Pcd]
+gSiPkgTokenSpaceGuid.PcdSiIoApicBaseAddress
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemId
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemRevision
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
+gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
+
+[FixedPcd]
+
+[Guids]
+gPchInfoHobGuid          ## CONSUMES
+gSaAcpiTableStorageGuid
+gVtdDataHobGuid
+gVtdDxeConfigGuid
+
+[Protocols]
+gSaPolicyProtocolGuid                  ## CONSUMES
+gSaNvsAreaProtocolGuid                 ## CONSUMES
+gEfiFirmwareVolume2ProtocolGuid
+gEfiAcpiTableProtocolGuid
+
+[Depex]
+gEfiAcpiTableProtocolGuid AND
+gEfiFirmwareVolume2ProtocolGuid AND
+gSaPolicyProtocolGuid AND
+gEfiPciRootBridgeIoProtocolGuid AND
+gEfiPciHostBridgeResourceAllocationProtocolGuid AND # This is to ensure that PCI MMIO resource has been prepared and available for this driver to allocate.
+gEfiHiiDatabaseProtocolGuid
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyLib/DxeVtdPolicyLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyLib/DxeVtdPolicyLib.c
new file mode 100644
index 0000000000..168de0c0a9
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyLib/DxeVtdPolicyLib.c
@@ -0,0 +1,90 @@
+/** @file
+  This file provides services for DXE VTD policy default initialization
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DxeVtdPolicyLib.h>
+
+/**
+  This function prints the DXE phase VTD policy.
+
+  @param[in] SaPolicy - Instance of SA_POLICY_PROTOCOL
+**/
+VOID
+VtdPrintPolicyDxe (
+  IN  SA_POLICY_PROTOCOL      *SaPolicy
+  )
+{
+  EFI_STATUS                  Status;
+  VTD_DXE_CONFIG             *VtdDxeConfig;
+
+  //
+  // Get requisite IP Config Blocks which needs to be used here
+  //
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gVtdDxeConfigGuid, (VOID *)&VtdDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG_CODE_BEGIN ();
+  DEBUG ((DEBUG_INFO, "\n------------------------ Vtd Policy (DXE) print BEGIN -----------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %d\n", VtdDxeConfig->Header.Revision));
+  ASSERT (VtdDxeConfig->Header.Revision == VTD_DXE_CONFIG_REVISION);
+  DEBUG ((DEBUG_INFO, "\n------------------------ Vtd Policy (DXE) print END -----------------\n"));
+  DEBUG_CODE_END ();
+  return;
+}
+
+/**
+  This function Load default Vtd DXE policy.
+
+  @param[in] ConfigBlockPointer    The pointer to add VTD config block
+**/
+VOID
+VtdLoadDefaultDxe (
+  IN VOID    *ConfigBlockPointer
+  )
+{
+  VTD_DXE_CONFIG        *VtdDxeConfig;
+
+  VtdDxeConfig = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "VtdDxeConfig->Header.GuidHob.Name = %g\n", &VtdDxeConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "VtdDxeConfig->Header.GuidHob.Header.HobLength = 0x%x\n", VtdDxeConfig->Header.GuidHob.Header.HobLength));
+}
+
+static COMPONENT_BLOCK_ENTRY  mVtdDxeIpBlock = {
+  &gVtdDxeConfigGuid, sizeof (VTD_DXE_CONFIG), VTD_DXE_CONFIG_REVISION, VtdLoadDefaultDxe
+};
+
+/**
+  Get VTD DXE config block table total size.
+
+  @retval     Size of VTD DXE config block table
+**/
+UINT16
+EFIAPI
+VtdGetConfigBlockTotalSizeDxe (
+  VOID
+  )
+{
+  return mVtdDxeIpBlock.Size;
+}
+
+/**
+  VtdAddConfigBlocks add VTD DXE config block.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add VTD config blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+VtdAddConfigBlocksDxe (
+  IN VOID           *ConfigBlockTableAddress
+  )
+{
+  EFI_STATUS  Status;
+  Status = AddComponentConfigBlocks (ConfigBlockTableAddress, &mVtdDxeIpBlock, 1);
+  return Status;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyLib/DxeVtdPolicyLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyLib/DxeVtdPolicyLib.inf
new file mode 100644
index 0000000000..1fe288416a
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyLib/DxeVtdPolicyLib.inf
@@ -0,0 +1,35 @@
+## @file
+# Component description file for the DxeVtdPolicy library.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeVtdPolicyLib
+FILE_GUID = 54754C6D-4883-4B67-BBBA-49D241539BE7
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = DxeVtdPolicyLib
+
+[LibraryClasses]
+BaseMemoryLib
+UefiRuntimeServicesTableLib
+UefiBootServicesTableLib
+DebugLib
+PostCodeLib
+ConfigBlockLib
+HobLib
+SiConfigBlockLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Sources]
+DxeVtdPolicyLib.c
+
+[Guids]
+gVtdDxeConfigGuid
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 31/40] TigerlakeSiliconPkg/Library: Add package common library instances
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (28 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 30/40] TigerlakeSiliconPkg/IpBlock: Add Vtd component Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 32/40] TigerlakeSiliconPkg/Pch: Add Pch " Heng Luo
                   ` (8 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * Library/BasePciSegmentMultiSegLibPci
  * Library/BaseSiConfigBlockLib
  * Library/PeiDxeSmmMmPciLib

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/BasePciSegmentMultiSegLibPci.inf |   38 +++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/BasePciSegmentMultiSegLibPci.uni |   14 ++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/PciSegmentLib.c                  | 1280 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.c                   |   86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf                 |   33 +++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.c                         |   35 +++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.inf                       |   43 ++++++++++++++++++++++++++++++
 7 files changed, 1529 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/BasePciSegmentMultiSegLibPci.inf b/Silicon/Intel/TigerlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/BasePciSegmentMultiSegLibPci.inf
new file mode 100644
index 0000000000..b04bce9cf0
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/BasePciSegmentMultiSegLibPci.inf
@@ -0,0 +1,38 @@
+## @file
+# Instance of PCI Segment Library based on PCI Library.
+#
+# PCI Segment Library that layers on top of the PCI Library which only
+#  supports segment 0 and segment 1 PCI configuration access.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BasePciSegmentMultiSegLibPci
+  MODULE_UNI_FILE                = BasePciSegmentMultiSegLibPci.uni
+  FILE_GUID                      = AC65B409-DF03-466e-8D2B-6FCE1079F0B2
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PciSegmentLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
+#
+
+[Sources]
+  PciSegmentLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  TigerlakeSiliconPkg/SiPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  PciLib
+  DebugLib
+  PcdLib
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/BasePciSegmentMultiSegLibPci.uni b/Silicon/Intel/TigerlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/BasePciSegmentMultiSegLibPci.uni
new file mode 100644
index 0000000000..09bd0f5cfc
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/BasePciSegmentMultiSegLibPci.uni
@@ -0,0 +1,14 @@
+/** @file
+  Instance of PCI Segment Library based on PCI Library.
+
+  PCI Segment Library that layers on top of the PCI Library which only
+   supports segment 0 and segment 1 PCI configuration access.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+
+#string STR_MODULE_ABSTRACT             #language en-US "Instance of PCI Segment Library based on PCI Library."
+
+#string STR_MODULE_DESCRIPTION          #language en-US "PCI Segment Library that layers on top of the PCI Library which only supports segment 0 and segment 1 PCI configuration access."
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/PciSegmentLib.c b/Silicon/Intel/TigerlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/PciSegmentLib.c
new file mode 100644
index 0000000000..0d0c64be3f
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Library/BasePciSegmentMultiSegLibPci/PciSegmentLib.c
@@ -0,0 +1,1280 @@
+/** @file
+  PCI Segment Library that layers on top of the PCI Library which only
+   supports segment 0 and segment 1 PCI configuration access.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PciLib.h>
+#include <Library/PciSegmentLib.h>
+
+/**
+  Assert the validity of a PCI Segment address.
+  A valid PCI Segment address should not contain 1's in bits 28..31 and 33..63
+  and the segment should be 0 or 1.
+
+  @param  A The address to validate.
+  @param  M Additional bits to assert to be zero.
+
+**/
+#define ASSERT_INVALID_PCI_SEGMENT_ADDRESS(A,M) \
+  ASSERT (((A) & (0xfffffffef0000000ULL | (M))) == 0)
+
+/**
+  Convert the PCI Segment library address to PCI library address.
+  From ICL generation support the multiple segment, and the segment number start from BIT28,
+  So we convert the Segment Number offset from BIT32 to BIT28
+
+  @param A The address to convert.
+**/
+#define PCI_SEGMENT_TO_PCI_ADDRESS(A) ((UINTN) (UINT32) ((A) | ((RShiftU64 ((A) & BIT32, 4)))))
+
+/**
+  Register a PCI device so PCI configuration registers may be accessed after
+  SetVirtualAddressMap().
+
+  If any reserved bits in Address are set, then ASSERT().
+
+  @param  Address The address that encodes the PCI Bus, Device, Function and
+                  Register.
+
+  @retval RETURN_SUCCESS           The PCI device was registered for runtime access.
+  @retval RETURN_UNSUPPORTED       An attempt was made to call this function
+                                   after ExitBootServices().
+  @retval RETURN_UNSUPPORTED       The resources required to access the PCI device
+                                   at runtime could not be mapped.
+  @retval RETURN_OUT_OF_RESOURCES  There are not enough resources available to
+                                   complete the registration.
+
+**/
+RETURN_STATUS
+EFIAPI
+PciSegmentRegisterForRuntimeAccess (
+  IN UINTN  Address
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
+  return PciRegisterForRuntimeAccess (PCI_SEGMENT_TO_PCI_ADDRESS (Address));
+}
+
+/**
+  Reads an 8-bit PCI configuration register.
+
+  Reads and returns the 8-bit PCI configuration register specified by Address.
+  This function must guarantee that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+
+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+
+  @return The 8-bit PCI configuration register specified by Address.
+
+**/
+UINT8
+EFIAPI
+PciSegmentRead8 (
+  IN UINT64                    Address
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
+
+  return PciRead8 (PCI_SEGMENT_TO_PCI_ADDRESS (Address));
+}
+
+/**
+  Writes an 8-bit PCI configuration register.
+
+  Writes the 8-bit PCI configuration register specified by Address with the value specified by Value.
+  Value is returned.  This function must guarantee that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+
+  @param  Address     The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  Value       The value to write.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentWrite8 (
+  IN UINT64                    Address,
+  IN UINT8                     Value
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);
+
+  return PciWrite8 (PCI_SEGMENT_TO_PCI_ADDRESS (Address), Value);
+}
+
+/**
+  Performs a bitwise OR of an 8-bit PCI configuration register with an 8-bit value.
+
+  Reads the 8-bit PCI configuration register specified by Address,
+  performs a bitwise OR between the read result and the value specified by OrData,
+  and writes the result to the 8-bit PCI configuration register specified by Address.
+  The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+
+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentOr8 (
+  IN UINT64                    Address,
+  IN UINT8                     OrData
+  )
+{
+  return PciWrite8 (PCI_SEGMENT_TO_PCI_ADDRESS (Address), (UINT8) (PciSegmentRead8 (Address) | OrData));
+}
+
+/**
+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value.
+
+  Reads the 8-bit PCI configuration register specified by Address,
+  performs a bitwise AND between the read result and the value specified by AndData,
+  and writes the result to the 8-bit PCI configuration register specified by Address.
+  The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations are serialized.
+  If any reserved bits in Address are set, then ASSERT().
+
+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  AndData   The value to AND with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentAnd8 (
+  IN UINT64                    Address,
+  IN UINT8                     AndData
+  )
+{
+  return PciSegmentWrite8 (Address, (UINT8) (PciSegmentRead8 (Address) & AndData));
+}
+
+/**
+  Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value,
+  followed a  bitwise OR with another 8-bit value.
+
+  Reads the 8-bit PCI configuration register specified by Address,
+  performs a bitwise AND between the read result and the value specified by AndData,
+  performs a bitwise OR between the result of the AND operation and the value specified by OrData,
+  and writes the result to the 8-bit PCI configuration register specified by Address.
+  The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+
+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  AndData    The value to AND with the PCI configuration register.
+  @param  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentAndThenOr8 (
+  IN UINT64                    Address,
+  IN UINT8                     AndData,
+  IN UINT8                     OrData
+  )
+{
+  return PciSegmentWrite8 (Address, (UINT8) ((PciSegmentRead8 (Address) & AndData) | OrData));
+}
+
+/**
+  Reads a bit field of a PCI configuration register.
+
+  Reads the bit field in an 8-bit PCI configuration register. The bit field is
+  specified by the StartBit and the EndBit. The value of the bit field is
+  returned.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+
+  @param  Address   The PCI configuration register to read.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..7.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..7.
+
+  @return The value of the bit field read from the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentBitFieldRead8 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit
+  )
+{
+  return BitFieldRead8 (PciSegmentRead8 (Address), StartBit, EndBit);
+}
+
+/**
+  Writes a bit field to a PCI configuration register.
+
+  Writes Value to the bit field of the PCI configuration register. The bit
+  field is specified by the StartBit and the EndBit. All other bits in the
+  destination PCI configuration register are preserved. The new value of the
+  8-bit register is returned.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Address   The PCI configuration register to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..7.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..7.
+  @param  Value     The new value of the bit field.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentBitFieldWrite8 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit,
+  IN UINT8                     Value
+  )
+{
+  return PciSegmentWrite8 (
+           Address,
+           BitFieldWrite8 (PciSegmentRead8 (Address), StartBit, EndBit, Value)
+           );
+}
+
+/**
+  Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
+  writes the result back to the bit field in the 8-bit port.
+
+  Reads the 8-bit PCI configuration register specified by Address, performs a
+  bitwise OR between the read result and the value specified by
+  OrData, and writes the result to the 8-bit PCI configuration register
+  specified by Address. The value written to the PCI configuration register is
+  returned. This function must guarantee that all PCI read and write operations
+  are serialized. Extra left bits in OrData are stripped.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Address   The PCI configuration register to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..7.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..7.
+  @param  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentBitFieldOr8 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit,
+  IN UINT8                     OrData
+  )
+{
+  return PciSegmentWrite8 (
+           Address,
+           BitFieldOr8 (PciSegmentRead8 (Address), StartBit, EndBit, OrData)
+           );
+}
+
+/**
+  Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
+  AND, and writes the result back to the bit field in the 8-bit register.
+
+  Reads the 8-bit PCI configuration register specified by Address, performs a
+  bitwise AND between the read result and the value specified by AndData, and
+  writes the result to the 8-bit PCI configuration register specified by
+  Address. The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations are
+  serialized. Extra left bits in AndData are stripped.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Address   The PCI configuration register to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..7.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..7.
+  @param  AndData   The value to AND with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentBitFieldAnd8 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit,
+  IN UINT8                     AndData
+  )
+{
+  return PciSegmentWrite8 (
+           Address,
+           BitFieldAnd8 (PciSegmentRead8 (Address), StartBit, EndBit, AndData)
+           );
+}
+
+/**
+  Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
+  bitwise OR, and writes the result back to the bit field in the
+  8-bit port.
+
+  Reads the 8-bit PCI configuration register specified by Address, performs a
+  bitwise AND followed by a bitwise OR between the read result and
+  the value specified by AndData, and writes the result to the 8-bit PCI
+  configuration register specified by Address. The value written to the PCI
+  configuration register is returned. This function must guarantee that all PCI
+  read and write operations are serialized. Extra left bits in both AndData and
+  OrData are stripped.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Address   The PCI configuration register to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..7.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..7.
+  @param  AndData   The value to AND with the PCI configuration register.
+  @param  OrData    The value to OR with the result of the AND operation.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciSegmentBitFieldAndThenOr8 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit,
+  IN UINT8                     AndData,
+  IN UINT8                     OrData
+  )
+{
+  return PciSegmentWrite8 (
+           Address,
+           BitFieldAndThenOr8 (PciSegmentRead8 (Address), StartBit, EndBit, AndData, OrData)
+           );
+}
+
+/**
+  Reads a 16-bit PCI configuration register.
+
+  Reads and returns the 16-bit PCI configuration register specified by Address.
+  This function must guarantee that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+
+  @return The 16-bit PCI configuration register specified by Address.
+
+**/
+UINT16
+EFIAPI
+PciSegmentRead16 (
+  IN UINT64                    Address
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);
+
+  return PciRead16 (PCI_SEGMENT_TO_PCI_ADDRESS (Address));
+}
+
+/**
+  Writes a 16-bit PCI configuration register.
+
+  Writes the 16-bit PCI configuration register specified by Address with the value specified by Value.
+  Value is returned.  This function must guarantee that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param  Address     The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  Value       The value to write.
+
+  @return The parameter of Value.
+
+**/
+UINT16
+EFIAPI
+PciSegmentWrite16 (
+  IN UINT64                    Address,
+  IN UINT16                    Value
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);
+
+  return PciWrite16 (PCI_SEGMENT_TO_PCI_ADDRESS (Address), Value);
+}
+
+/**
+  Performs a bitwise OR of a 16-bit PCI configuration register with
+  a 16-bit value.
+
+  Reads the 16-bit PCI configuration register specified by Address, performs a
+  bitwise OR between the read result and the value specified by
+  OrData, and writes the result to the 16-bit PCI configuration register
+  specified by Address. The value written to the PCI configuration register is
+  returned. This function must guarantee that all PCI read and write operations
+  are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param  Address The address that encodes the PCI Segment, Bus, Device, Function and
+                  Register.
+  @param  OrData  The value to OR with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciSegmentOr16 (
+  IN UINT64                    Address,
+  IN UINT16                    OrData
+  )
+{
+  return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 (Address) | OrData));
+}
+
+/**
+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value.
+
+  Reads the 16-bit PCI configuration register specified by Address,
+  performs a bitwise AND between the read result and the value specified by AndData,
+  and writes the result to the 16-bit PCI configuration register specified by Address.
+  The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  AndData   The value to AND with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciSegmentAnd16 (
+  IN UINT64                    Address,
+  IN UINT16                    AndData
+  )
+{
+  return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 (Address) & AndData));
+}
+
+/**
+  Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value,
+  followed a  bitwise OR with another 16-bit value.
+
+  Reads the 16-bit PCI configuration register specified by Address,
+  performs a bitwise AND between the read result and the value specified by AndData,
+  performs a bitwise OR between the result of the AND operation and the value specified by OrData,
+  and writes the result to the 16-bit PCI configuration register specified by Address.
+  The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  AndData    The value to AND with the PCI configuration register.
+  @param  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciSegmentAndThenOr16 (
+  IN UINT64                    Address,
+  IN UINT16                    AndData,
+  IN UINT16                    OrData
+  )
+{
+  return PciSegmentWrite16 (Address, (UINT16) ((PciSegmentRead16 (Address) & AndData) | OrData));
+}
+
+/**
+  Reads a bit field of a PCI configuration register.
+
+  Reads the bit field in a 16-bit PCI configuration register. The bit field is
+  specified by the StartBit and the EndBit. The value of the bit field is
+  returned.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+  If StartBit is greater than 15, then ASSERT().
+  If EndBit is greater than 15, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+
+  @param  Address   The PCI configuration register to read.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..15.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..15.
+
+  @return The value of the bit field read from the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciSegmentBitFieldRead16 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit
+  )
+{
+  return BitFieldRead16 (PciSegmentRead16 (Address), StartBit, EndBit);
+}
+
+/**
+  Writes a bit field to a PCI configuration register.
+
+  Writes Value to the bit field of the PCI configuration register. The bit
+  field is specified by the StartBit and the EndBit. All other bits in the
+  destination PCI configuration register are preserved. The new value of the
+  16-bit register is returned.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+  If StartBit is greater than 15, then ASSERT().
+  If EndBit is greater than 15, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Address   The PCI configuration register to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..15.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..15.
+  @param  Value     The new value of the bit field.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciSegmentBitFieldWrite16 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit,
+  IN UINT16                    Value
+  )
+{
+  return PciSegmentWrite16 (
+           Address,
+           BitFieldWrite16 (PciSegmentRead16 (Address), StartBit, EndBit, Value)
+           );
+}
+
+/**
+  Reads the 16-bit PCI configuration register specified by Address,
+  performs a bitwise OR between the read result and the value specified by OrData,
+  and writes the result to the 16-bit PCI configuration register specified by Address.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+  If StartBit is greater than 15, then ASSERT().
+  If EndBit is greater than 15, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Address   The PCI configuration register to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..15.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..15.
+  @param  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciSegmentBitFieldOr16 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit,
+  IN UINT16                    OrData
+  )
+{
+  return PciSegmentWrite16 (
+           Address,
+           BitFieldOr16 (PciSegmentRead16 (Address), StartBit, EndBit, OrData)
+           );
+}
+
+/**
+  Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR,
+  and writes the result back to the bit field in the 16-bit port.
+
+  Reads the 16-bit PCI configuration register specified by Address,
+  performs a bitwise OR between the read result and the value specified by OrData,
+  and writes the result to the 16-bit PCI configuration register specified by Address.
+  The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations are serialized.
+  Extra left bits in OrData are stripped.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+  If StartBit is greater than 7, then ASSERT().
+  If EndBit is greater than 7, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    The ordinal of the least significant bit in a byte is bit 0.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    The ordinal of the most significant bit in a byte is bit 7.
+  @param  AndData   The value to AND with the read value from the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciSegmentBitFieldAnd16 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit,
+  IN UINT16                    AndData
+  )
+{
+  return PciSegmentWrite16 (
+           Address,
+           BitFieldAnd16 (PciSegmentRead16 (Address), StartBit, EndBit, AndData)
+           );
+}
+
+/**
+  Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
+  bitwise OR, and writes the result back to the bit field in the
+  16-bit port.
+
+  Reads the 16-bit PCI configuration register specified by Address, performs a
+  bitwise AND followed by a bitwise OR between the read result and
+  the value specified by AndData, and writes the result to the 16-bit PCI
+  configuration register specified by Address. The value written to the PCI
+  configuration register is returned. This function must guarantee that all PCI
+  read and write operations are serialized. Extra left bits in both AndData and
+  OrData are stripped.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If StartBit is greater than 15, then ASSERT().
+  If EndBit is greater than 15, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Address   The PCI configuration register to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..15.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..15.
+  @param  AndData   The value to AND with the PCI configuration register.
+  @param  OrData    The value to OR with the result of the AND operation.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciSegmentBitFieldAndThenOr16 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit,
+  IN UINT16                    AndData,
+  IN UINT16                    OrData
+  )
+{
+  return PciSegmentWrite16 (
+           Address,
+           BitFieldAndThenOr16 (PciSegmentRead16 (Address), StartBit, EndBit, AndData, OrData)
+           );
+}
+
+/**
+  Reads a 32-bit PCI configuration register.
+
+  Reads and returns the 32-bit PCI configuration register specified by Address.
+  This function must guarantee that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+
+  @return The 32-bit PCI configuration register specified by Address.
+
+**/
+UINT32
+EFIAPI
+PciSegmentRead32 (
+  IN UINT64                    Address
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);
+
+  return PciRead32 (PCI_SEGMENT_TO_PCI_ADDRESS (Address));
+}
+
+/**
+  Writes a 32-bit PCI configuration register.
+
+  Writes the 32-bit PCI configuration register specified by Address with the value specified by Value.
+  Value is returned.  This function must guarantee that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param  Address     The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  Value       The value to write.
+
+  @return The parameter of Value.
+
+**/
+UINT32
+EFIAPI
+PciSegmentWrite32 (
+  IN UINT64                    Address,
+  IN UINT32                    Value
+  )
+{
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);
+
+  return PciWrite32 (PCI_SEGMENT_TO_PCI_ADDRESS (Address), Value);
+}
+
+/**
+  Performs a bitwise OR of a 32-bit PCI configuration register with a 32-bit value.
+
+  Reads the 32-bit PCI configuration register specified by Address,
+  performs a bitwise OR between the read result and the value specified by OrData,
+  and writes the result to the 32-bit PCI configuration register specified by Address.
+  The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciSegmentOr32 (
+  IN UINT64                    Address,
+  IN UINT32                    OrData
+  )
+{
+  return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) | OrData);
+}
+
+/**
+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value.
+
+  Reads the 32-bit PCI configuration register specified by Address,
+  performs a bitwise AND between the read result and the value specified by AndData,
+  and writes the result to the 32-bit PCI configuration register specified by Address.
+  The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  AndData   The value to AND with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciSegmentAnd32 (
+  IN UINT64                    Address,
+  IN UINT32                    AndData
+  )
+{
+  return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) & AndData);
+}
+
+/**
+  Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value,
+  followed a  bitwise OR with another 32-bit value.
+
+  Reads the 32-bit PCI configuration register specified by Address,
+  performs a bitwise AND between the read result and the value specified by AndData,
+  performs a bitwise OR between the result of the AND operation and the value specified by OrData,
+  and writes the result to the 32-bit PCI configuration register specified by Address.
+  The value written to the PCI configuration register is returned.
+  This function must guarantee that all PCI read and write operations are serialized.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param  Address   The address that encodes the PCI Segment, Bus, Device, Function, and Register.
+  @param  AndData   The value to AND with the PCI configuration register.
+  @param  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciSegmentAndThenOr32 (
+  IN UINT64                    Address,
+  IN UINT32                    AndData,
+  IN UINT32                    OrData
+  )
+{
+  return PciSegmentWrite32 (Address, (PciSegmentRead32 (Address) & AndData) | OrData);
+}
+
+/**
+  Reads a bit field of a PCI configuration register.
+
+  Reads the bit field in a 32-bit PCI configuration register. The bit field is
+  specified by the StartBit and the EndBit. The value of the bit field is
+  returned.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+
+  @param  Address   The PCI configuration register to read.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..31.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..31.
+
+  @return The value of the bit field read from the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciSegmentBitFieldRead32 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit
+  )
+{
+  return BitFieldRead32 (PciSegmentRead32 (Address), StartBit, EndBit);
+}
+
+/**
+  Writes a bit field to a PCI configuration register.
+
+  Writes Value to the bit field of the PCI configuration register. The bit
+  field is specified by the StartBit and the EndBit. All other bits in the
+  destination PCI configuration register are preserved. The new value of the
+  32-bit register is returned.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Address   The PCI configuration register to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..31.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..31.
+  @param  Value     The new value of the bit field.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciSegmentBitFieldWrite32 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit,
+  IN UINT32                    Value
+  )
+{
+  return PciSegmentWrite32 (
+           Address,
+           BitFieldWrite32 (PciSegmentRead32 (Address), StartBit, EndBit, Value)
+           );
+}
+
+/**
+  Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
+  writes the result back to the bit field in the 32-bit port.
+
+  Reads the 32-bit PCI configuration register specified by Address, performs a
+  bitwise OR between the read result and the value specified by
+  OrData, and writes the result to the 32-bit PCI configuration register
+  specified by Address. The value written to the PCI configuration register is
+  returned. This function must guarantee that all PCI read and write operations
+  are serialized. Extra left bits in OrData are stripped.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Address   The PCI configuration register to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..31.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..31.
+  @param  OrData    The value to OR with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciSegmentBitFieldOr32 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit,
+  IN UINT32                    OrData
+  )
+{
+  return PciSegmentWrite32 (
+           Address,
+           BitFieldOr32 (PciSegmentRead32 (Address), StartBit, EndBit, OrData)
+           );
+}
+
+/**
+  Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
+  AND, and writes the result back to the bit field in the 32-bit register.
+
+
+  Reads the 32-bit PCI configuration register specified by Address, performs a bitwise
+  AND between the read result and the value specified by AndData, and writes the result
+  to the 32-bit PCI configuration register specified by Address. The value written to
+  the PCI configuration register is returned.  This function must guarantee that all PCI
+  read and write operations are serialized.  Extra left bits in AndData are stripped.
+  If any reserved bits in Address are set, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Address   The PCI configuration register to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..31.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..31.
+  @param  AndData   The value to AND with the PCI configuration register.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciSegmentBitFieldAnd32 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit,
+  IN UINT32                    AndData
+  )
+{
+  return PciSegmentWrite32 (
+           Address,
+           BitFieldAnd32 (PciSegmentRead32 (Address), StartBit, EndBit, AndData)
+           );
+}
+
+/**
+  Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
+  bitwise OR, and writes the result back to the bit field in the
+  32-bit port.
+
+  Reads the 32-bit PCI configuration register specified by Address, performs a
+  bitwise AND followed by a bitwise OR between the read result and
+  the value specified by AndData, and writes the result to the 32-bit PCI
+  configuration register specified by Address. The value written to the PCI
+  configuration register is returned. This function must guarantee that all PCI
+  read and write operations are serialized. Extra left bits in both AndData and
+  OrData are stripped.
+
+  If any reserved bits in Address are set, then ASSERT().
+  If StartBit is greater than 31, then ASSERT().
+  If EndBit is greater than 31, then ASSERT().
+  If EndBit is less than StartBit, then ASSERT().
+  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+  @param  Address   The PCI configuration register to write.
+  @param  StartBit  The ordinal of the least significant bit in the bit field.
+                    Range 0..31.
+  @param  EndBit    The ordinal of the most significant bit in the bit field.
+                    Range 0..31.
+  @param  AndData   The value to AND with the PCI configuration register.
+  @param  OrData    The value to OR with the result of the AND operation.
+
+  @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciSegmentBitFieldAndThenOr32 (
+  IN UINT64                    Address,
+  IN UINTN                     StartBit,
+  IN UINTN                     EndBit,
+  IN UINT32                    AndData,
+  IN UINT32                    OrData
+  )
+{
+  return PciSegmentWrite32 (
+           Address,
+           BitFieldAndThenOr32 (PciSegmentRead32 (Address), StartBit, EndBit, AndData, OrData)
+           );
+}
+
+/**
+  Reads a range of PCI configuration registers into a caller supplied buffer.
+
+  Reads the range of PCI configuration registers specified by StartAddress and
+  Size into the buffer specified by Buffer. This function only allows the PCI
+  configuration registers from a single PCI function to be read. Size is
+  returned. When possible 32-bit PCI configuration read cycles are used to read
+  from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
+  and 16-bit PCI configuration read cycles may be used at the beginning and the
+  end of the range.
+
+  If any reserved bits in StartAddress are set, then ASSERT().
+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+  If Size > 0 and Buffer is NULL, then ASSERT().
+
+  @param  StartAddress  The starting address that encodes the PCI Segment, Bus, Device,
+                        Function and Register.
+  @param  Size          The size in bytes of the transfer.
+  @param  Buffer        The pointer to a buffer receiving the data read.
+
+  @return Size
+
+**/
+UINTN
+EFIAPI
+PciSegmentReadBuffer (
+  IN  UINT64                   StartAddress,
+  IN  UINTN                    Size,
+  OUT VOID                     *Buffer
+  )
+{
+  UINTN                                ReturnValue;
+
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);
+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);
+
+  if (Size == 0) {
+    return Size;
+  }
+
+  ASSERT (Buffer != NULL);
+
+  //
+  // Save Size for return
+  //
+  ReturnValue = Size;
+
+  if ((StartAddress & BIT0) != 0) {
+    //
+    // Read a byte if StartAddress is byte aligned
+    //
+    *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);
+    StartAddress += sizeof (UINT8);
+    Size -= sizeof (UINT8);
+    Buffer = (UINT8*)Buffer + 1;
+  }
+
+  if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {
+    //
+    // Read a word if StartAddress is word aligned
+    //
+    WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));
+    StartAddress += sizeof (UINT16);
+    Size -= sizeof (UINT16);
+    Buffer = (UINT16*)Buffer + 1;
+  }
+
+  while (Size >= sizeof (UINT32)) {
+    //
+    // Read as many double words as possible
+    //
+    WriteUnaligned32 (Buffer, PciSegmentRead32 (StartAddress));
+    StartAddress += sizeof (UINT32);
+    Size -= sizeof (UINT32);
+    Buffer = (UINT32*)Buffer + 1;
+  }
+
+  if (Size >= sizeof (UINT16)) {
+    //
+    // Read the last remaining word if exist
+    //
+    WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));
+    StartAddress += sizeof (UINT16);
+    Size -= sizeof (UINT16);
+    Buffer = (UINT16*)Buffer + 1;
+  }
+
+  if (Size >= sizeof (UINT8)) {
+    //
+    // Read the last remaining byte if exist
+    //
+    *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);
+  }
+
+  return ReturnValue;
+}
+
+/**
+  Copies the data in a caller supplied buffer to a specified range of PCI
+  configuration space.
+
+  Writes the range of PCI configuration registers specified by StartAddress and
+  Size from the buffer specified by Buffer. This function only allows the PCI
+  configuration registers from a single PCI function to be written. Size is
+  returned. When possible 32-bit PCI configuration write cycles are used to
+  write from StartAdress to StartAddress + Size. Due to alignment restrictions,
+  8-bit and 16-bit PCI configuration write cycles may be used at the beginning
+  and the end of the range.
+
+  If any reserved bits in StartAddress are set, then ASSERT().
+  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+  If Size > 0 and Buffer is NULL, then ASSERT().
+
+  @param  StartAddress  The starting address that encodes the PCI Segment, Bus, Device,
+                        Function and Register.
+  @param  Size          The size in bytes of the transfer.
+  @param  Buffer        The pointer to a buffer containing the data to write.
+
+  @return The parameter of Size.
+
+**/
+UINTN
+EFIAPI
+PciSegmentWriteBuffer (
+  IN UINT64                    StartAddress,
+  IN UINTN                     Size,
+  IN VOID                      *Buffer
+  )
+{
+  UINTN                                ReturnValue;
+
+  ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);
+  ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);
+
+  if (Size == 0) {
+    return 0;
+  }
+
+  ASSERT (Buffer != NULL);
+
+  //
+  // Save Size for return
+  //
+  ReturnValue = Size;
+
+  if ((StartAddress & BIT0) != 0) {
+    //
+    // Write a byte if StartAddress is byte aligned
+    //
+    PciSegmentWrite8 (StartAddress, *(UINT8*) Buffer);
+    StartAddress += sizeof (UINT8);
+    Size -= sizeof (UINT8);
+    Buffer = (UINT8*) Buffer + 1;
+  }
+
+  if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {
+    //
+    // Write a word if StartAddress is word aligned
+    //
+    PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));
+    StartAddress += sizeof (UINT16);
+    Size -= sizeof (UINT16);
+    Buffer = (UINT16*) Buffer + 1;
+  }
+
+  while (Size >= sizeof (UINT32)) {
+    //
+    // Write as many double words as possible
+    //
+    PciSegmentWrite32 (StartAddress, ReadUnaligned32 (Buffer));
+    StartAddress += sizeof (UINT32);
+    Size -= sizeof (UINT32);
+    Buffer = (UINT32*) Buffer + 1;
+  }
+
+  if (Size >= sizeof (UINT16)) {
+    //
+    // Write the last remaining word if exist
+    //
+    PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));
+    StartAddress += sizeof (UINT16);
+    Size -= sizeof (UINT16);
+    Buffer = (UINT16*) Buffer + 1;
+  }
+
+  if (Size >= sizeof (UINT8)) {
+    //
+    // Write the last remaining byte if exist
+    //
+    PciSegmentWrite8 (StartAddress, *(UINT8*) Buffer);
+  }
+
+  return ReturnValue;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.c b/Silicon/Intel/TigerlakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.c
new file mode 100644
index 0000000000..4644de9b74
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.c
@@ -0,0 +1,86 @@
+/** @file
+  This file is BaseSiConfigBlockLib library is used to add config blocks
+  to config block header.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <ConfigBlock.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/SiConfigBlockLib.h>
+
+
+/**
+  GetComponentConfigBlockTotalSize get config block table total size.
+
+  @param[in] ComponentBlocks    Component blocks array
+  @param[in] TotalBlockCount    Number of blocks
+
+  @retval                       Size of config block table
+**/
+UINT16
+EFIAPI
+GetComponentConfigBlockTotalSize (
+  IN COMPONENT_BLOCK_ENTRY *ComponentBlocks,
+  IN UINT16                TotalBlockCount
+  )
+{
+  UINT16            TotalBlockSize;
+  UINT16            BlockCount;
+
+  TotalBlockSize = 0;
+  for (BlockCount = 0 ; BlockCount < TotalBlockCount; BlockCount++) {
+    TotalBlockSize += (UINT32) ComponentBlocks[BlockCount].Size;
+    DEBUG ((DEBUG_INFO, "TotalBlockSize after adding Block[0x%x]= 0x%x\n", BlockCount, TotalBlockSize));
+  }
+
+  return TotalBlockSize;
+}
+
+/**
+  AddComponentConfigBlocks add all config blocks.
+
+  @param[in] ConfigBlockTableAddress    The pointer to add config blocks
+  @param[in] ComponentBlocks            Config blocks array
+  @param[in] TotalBlockCount            Number of blocks
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+AddComponentConfigBlocks (
+  IN VOID                  *ConfigBlockTableAddress,
+  IN COMPONENT_BLOCK_ENTRY *ComponentBlocks,
+  IN UINT16                TotalBlockCount
+  )
+{
+  UINT16            BlockCount;
+  VOID              *ConfigBlockPointer;
+  CONFIG_BLOCK      ConfigBlockBuf;
+  EFI_STATUS        Status;
+
+  Status = EFI_SUCCESS;
+
+  //
+  // Initialize ConfigBlockPointer to NULL
+  //
+  ConfigBlockPointer = NULL;
+  //
+  // Loop to identify each config block from ComponentBlocks[] Table and add each of them
+  //
+  for (BlockCount = 0; BlockCount < TotalBlockCount; BlockCount++) {
+    ZeroMem (&ConfigBlockBuf, sizeof (CONFIG_BLOCK));
+    CopyMem (&(ConfigBlockBuf.Header.GuidHob.Name), ComponentBlocks[BlockCount].Guid, sizeof (EFI_GUID));
+    ConfigBlockBuf.Header.GuidHob.Header.HobLength = ComponentBlocks[BlockCount].Size;
+    ConfigBlockBuf.Header.Revision        = ComponentBlocks[BlockCount].Revision;
+    ConfigBlockPointer = (VOID *)&ConfigBlockBuf;
+    Status = AddConfigBlock ((VOID *)ConfigBlockTableAddress, (VOID *)&ConfigBlockPointer);
+    ASSERT_EFI_ERROR (Status);
+    ComponentBlocks[BlockCount].LoadDefault (ConfigBlockPointer);
+  }
+  return Status;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf
new file mode 100644
index 0000000000..e23b2d342f
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf
@@ -0,0 +1,33 @@
+## @file
+# Component description file for the BaseSiConfigBlockLib library.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = BaseSiConfigBlockLib
+FILE_GUID = 6C068D0F-F48E-48CB-B369-433E507AF4A2
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = SiConfigBlockLib
+
+
+[LibraryClasses]
+DebugLib
+IoLib
+ConfigBlockLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+BaseSiConfigBlockLib.c
+
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.c b/Silicon/Intel/TigerlakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.c
new file mode 100644
index 0000000000..48e14dc9ee
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.c
@@ -0,0 +1,35 @@
+/** @file
+  This file contains routines that get PCI Express Address
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+/**
+  This procedure will get PCIE address
+
+  @param[in] Bus                  Pci Bus Number
+  @param[in] Device               Pci Device Number
+  @param[in] Function             Pci Function Number
+
+  @retval PCIE address
+**/
+UINTN
+EFIAPI
+MmPciBase (
+  IN UINT32                       Bus,
+  IN UINT32                       Device,
+  IN UINT32                       Function
+  )
+{
+  ASSERT ((Bus <= 0xFF) && (Device <= 0x1F) && (Function <= 0x7));
+
+#ifdef FSP_FLAG
+  return ((UINTN) PcdGet64 (PcdSiPciExpressBaseAddress) + (UINTN) (Bus << 20) + (UINTN) (Device << 15) + (UINTN) (Function << 12));
+#else
+  return ((UINTN) PcdGet64 (PcdPciExpressBaseAddress)   + (UINTN) (Bus << 20) + (UINTN) (Device << 15) + (UINTN) (Function << 12));
+#endif
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.inf
new file mode 100644
index 0000000000..353b97f3f6
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.inf
@@ -0,0 +1,43 @@
+## @file
+# Component description file for the PeiDxeSmmMmPciLib
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmMmPciLib
+FILE_GUID = D03D6670-A032-11E2-9E96-0800200C9A66
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = MmPciLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+
+
+[LibraryClasses]
+BaseLib
+PcdLib
+DebugLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+gSiPkgTokenSpaceGuid.PcdSiPciExpressBaseAddress
+
+[FixedPcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+[Sources]
+PeiDxeSmmMmPciLib.c
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 32/40] TigerlakeSiliconPkg/Pch: Add Pch common library instances
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (29 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 31/40] TigerlakeSiliconPkg/Library: Add package common library instances Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 33/40] TigerlakeSiliconPkg/Pch: Add Pch private " Heng Luo
                   ` (7 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * Pch/Library/BasePchPciBdfLib
  * Pch/Library/BaseResetSystemLib
  * Pch/Library/DxePchPolicyLib
  * Pch/Library/PeiDxeSmmPchCycleDecodingLib
  * Pch/Library/PeiDxeSmmPchInfoLib

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/BasePchPciBdfLib/BasePchPciBdfLib.inf                         |   33 +++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/BasePchPciBdfLib/PchPciBdfLib.c                               | 1092 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.c                       |  158 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.inf                     |   38 +++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.c                             |  198 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.inf                           |   43 +++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PchCycleDecodingLib.c            |  587 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PeiDxeSmmPchCycleDecodingLib.inf |   42 ++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLib.c                              |  127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibPrivate.h                       |   58 +++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibTgl.c                           |  715 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PeiDxeSmmPchInfoLibTgl.inf                |   43 +++++++++++++++++++++++++++++++++++
 12 files changed, 3134 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/BasePchPciBdfLib/BasePchPciBdfLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/BasePchPciBdfLib/BasePchPciBdfLib.inf
new file mode 100644
index 0000000000..4f4096a409
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/BasePchPciBdfLib/BasePchPciBdfLib.inf
@@ -0,0 +1,33 @@
+## @file
+# PCH PCIe Bus Device Function Library.
+#
+# All functions from this library are available in 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 = PeiDxeSmmPchPciBdfLib
+FILE_GUID = ED0C4241-40FA-4A74-B061-2E45E7AAD7BA
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchPciBdfLib
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PciSegmentLib
+PchInfoLib
+PchPcieRpLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Sources]
+PchPciBdfLib.c
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/BasePchPciBdfLib/PchPciBdfLib.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/BasePchPciBdfLib/PchPciBdfLib.c
new file mode 100644
index 0000000000..0db8cea4bb
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/BasePchPciBdfLib/PchPciBdfLib.c
@@ -0,0 +1,1092 @@
+/** @file
+  PCH PCIe Bus Device Function Library.
+  All functions from this library are available in 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 <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchPcieRpLib.h>
+#include <Register/PchRegs.h>
+#include <PchBdfAssignment.h>
+
+/**
+  Check if a Device is present for PCH FRU
+  If the data is defined for PCH RFU return it
+  If the data is not defined (Device is NOT present) assert.
+
+  @param[in]  DataToCheck       Device or Function number to check
+
+  @retval Device or Function number value if defined for PCH FRU
+          0xFF if not present in PCH FRU
+**/
+UINT8
+CheckAndReturn (
+  UINT8 DataToCheck
+  )
+{
+  if (DataToCheck == NOT_PRESENT) {
+    ASSERT (FALSE);
+  }
+  return DataToCheck;
+}
+
+/**
+  Get eSPI controller address that can be passed to the PCI Segment Library functions.
+
+  @retval eSPI controller address in PCI Segment Library representation
+**/
+UINT64
+EspiPciCfgBase (
+  VOID
+  )
+{
+  ASSERT (PCI_DEVICE_NUMBER_PCH_ESPI != NOT_PRESENT);
+
+  return PCI_SEGMENT_LIB_ADDRESS (
+           DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+           DEFAULT_PCI_BUS_NUMBER_PCH,
+           PCI_DEVICE_NUMBER_PCH_ESPI,
+           PCI_FUNCTION_NUMBER_PCH_ESPI,
+           0
+           );
+}
+
+/**
+  Returns Gigabit Ethernet PCI Device Number
+
+  @retval  GbE device number
+**/
+UINT8
+GbeDevNumber (
+  VOID
+  )
+{
+  return CheckAndReturn (PCI_DEVICE_NUMBER_GBE);
+}
+
+/**
+  Returns Gigabit Ethernet PCI Function Number
+
+  @retval  GbE function number
+**/
+UINT8
+GbeFuncNumber (
+  VOID
+  )
+{
+  return CheckAndReturn (PCI_FUNCTION_NUMBER_GBE);
+}
+
+/**
+  Get GbE controller address that can be passed to the PCI Segment Library functions.
+
+  @retval GbE controller address in PCI Segment Library representation
+**/
+UINT64
+GbePciCfgBase (
+  VOID
+  )
+{
+  return PCI_SEGMENT_LIB_ADDRESS (
+            DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+            DEFAULT_PCI_BUS_NUMBER_PCH,
+            GbeDevNumber (),
+            GbeFuncNumber (),
+            0
+            );
+}
+
+/**
+  Get HDA PCI device number
+
+  @retval PCI dev number
+**/
+UINT8
+HdaDevNumber (
+  VOID
+  )
+{
+  return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_HDA);
+}
+
+/**
+  Get HDA PCI function number
+
+  @retval PCI fun number
+**/
+UINT8
+HdaFuncNumber (
+  VOID
+  )
+{
+  return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_HDA);
+}
+
+/**
+  Get HDA controller address that can be passed to the PCI Segment Library functions.
+
+  @retval HDA controller address in PCI Segment Library representation
+**/
+UINT64
+HdaPciCfgBase (
+  VOID
+  )
+{
+  return PCI_SEGMENT_LIB_ADDRESS (
+            DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+            DEFAULT_PCI_BUS_NUMBER_PCH,
+            HdaDevNumber (),
+            HdaFuncNumber (),
+            0
+            );
+}
+
+/**
+  Get P2SB PCI device number
+
+  @retval PCI dev number
+**/
+UINT8
+P2sbDevNumber (
+  VOID
+  )
+{
+  return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_P2SB);
+}
+
+/**
+  Get P2SB PCI function number
+
+  @retval PCI fun number
+**/
+UINT8
+P2sbFuncNumber (
+  VOID
+  )
+{
+  return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_P2SB);
+}
+
+/**
+  Get P2SB controller address that can be passed to the PCI Segment Library functions.
+
+  @retval P2SB controller address in PCI Segment Library representation
+**/
+UINT64
+P2sbPciCfgBase (
+  VOID
+  )
+{
+  return PCI_SEGMENT_LIB_ADDRESS (
+           DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+           DEFAULT_PCI_BUS_NUMBER_PCH,
+           P2sbDevNumber (),
+           P2sbFuncNumber (),
+           0
+           );
+}
+
+/**
+  Returns PCH SPI Device number
+
+  @retval UINT8   PCH SPI Device number
+**/
+UINT8
+SpiDevNumber (
+  VOID
+  )
+{
+  return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SPI);
+}
+
+/**
+  Returns PCH SPI Function number
+
+  @retval UINT8   PCH SPI Function number
+**/
+UINT8
+SpiFuncNumber (
+  VOID
+  )
+{
+  return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SPI);
+}
+
+/**
+  Returns PCH SPI PCI Config Space base address
+
+  @retval  UINT64  PCH SPI Config Space base address
+**/
+UINT64
+SpiPciCfgBase (
+  VOID
+  )
+{
+  return PCI_SEGMENT_LIB_ADDRESS (
+           DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+           DEFAULT_PCI_BUS_NUMBER_PCH,
+           SpiDevNumber (),
+           SpiFuncNumber (),
+           0
+           );
+}
+
+/**
+  Get XHCI controller PCIe Device Number
+
+  @retval XHCI controller PCIe Device Number
+**/
+UINT8
+PchXhciDevNumber (
+  VOID
+  )
+{
+  return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_XHCI);
+}
+
+/**
+  Get XHCI controller PCIe Function Number
+
+  @retval XHCI controller PCIe Function Number
+**/
+UINT8
+PchXhciFuncNumber (
+  VOID
+  )
+{
+  return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_XHCI);
+}
+
+/**
+  Get XHCI controller address that can be passed to the PCI Segment Library functions.
+
+  @retval XHCI controller address in PCI Segment Library representation
+**/
+UINT64
+PchXhciPciCfgBase (
+  VOID
+  )
+{
+  return PCI_SEGMENT_LIB_ADDRESS (
+          DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+          DEFAULT_PCI_BUS_NUMBER_PCH,
+          PchXhciDevNumber (),
+          PchXhciFuncNumber (),
+          0
+          );
+}
+
+/**
+  Get XDCI controller PCIe Device Number
+
+  @retval XDCI controller PCIe Device Number
+**/
+UINT8
+PchXdciDevNumber (
+  VOID
+  )
+{
+  return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_XDCI);
+}
+
+/**
+  Get XDCI controller PCIe Function Number
+
+  @retval XDCI controller PCIe Function Number
+**/
+UINT8
+PchXdciFuncNumber (
+  VOID
+  )
+{
+  return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_XDCI);
+}
+
+/**
+  Get XDCI controller address that can be passed to the PCI Segment Library functions.
+
+  @retval XDCI controller address in PCI Segment Library representation
+**/
+UINT64
+PchXdciPciCfgBase (
+  VOID
+  )
+{
+  return PCI_SEGMENT_LIB_ADDRESS (
+          DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+          DEFAULT_PCI_BUS_NUMBER_PCH,
+          PchXdciDevNumber (),
+          PchXdciFuncNumber (),
+          0
+          );
+}
+
+/**
+  Return Smbus Device Number
+
+  @retval Smbus Device Number
+**/
+UINT8
+SmbusDevNumber (
+  VOID
+  )
+{
+  return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SMBUS);
+}
+
+/**
+  Return Smbus Function Number
+
+  @retval  Smbus Function Number
+**/
+UINT8
+SmbusFuncNumber (
+  VOID
+  )
+{
+  return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SMBUS);
+}
+
+/**
+  Get SMBUS controller address that can be passed to the PCI Segment Library functions.
+
+  @retval SMBUS controller address in PCI Segment Library representation
+**/
+UINT64
+SmbusPciCfgBase (
+  VOID
+  )
+{
+  return PCI_SEGMENT_LIB_ADDRESS (
+            DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+            DEFAULT_PCI_BUS_NUMBER_PCH,
+            SmbusDevNumber (),
+            SmbusFuncNumber (),
+            0
+            );
+}
+
+/**
+  Return DMA Smbus Device Number
+
+  @retval DMA Smbus Device Number
+**/
+UINT8
+SmbusDmaDevNumber (
+  VOID
+  )
+{
+  return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_DMA_SMBUS);
+}
+
+/**
+  Return DMA Smbus Function Number
+
+  @retval  DMA Smbus Function Number
+**/
+UINT8
+SmbusDmaFuncNumber (
+  VOID
+  )
+{
+  return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_DMA_SMBUS);
+}
+
+/**
+  Get DMA SMBUS controller address that can be passed to the PCI Segment Library functions.
+
+  @retval DMA SMBUS controller address in PCI Segment Library representation
+**/
+UINT64
+SmbusDmaPciCfgBase (
+  VOID
+  )
+{
+  return PCI_SEGMENT_LIB_ADDRESS (
+            DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+            DEFAULT_PCI_BUS_NUMBER_PCH,
+            SmbusDmaDevNumber (),
+            SmbusDmaFuncNumber (),
+            0
+            );
+}
+
+/**
+  Get SATA controller PCIe Device Number
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval SATA controller PCIe Device Number
+**/
+UINT8
+SataDevNumber (
+  IN UINT32  SataCtrlIndex
+  )
+{
+  ASSERT (SataCtrlIndex < MAX_SATA_CONTROLLER);
+
+  if (SataCtrlIndex == 0) {
+    return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SATA_1);
+  } else if (SataCtrlIndex == 1) {
+    return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SATA_2);
+  } else if (SataCtrlIndex == 2) {
+    return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SATA_3);
+  } else {
+    ASSERT (FALSE);
+    return 0xFF;
+  }
+}
+
+/**
+  Get SATA controller PCIe Function Number
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval SATA controller PCIe Function Number
+**/
+UINT8
+SataFuncNumber (
+  IN UINT32  SataCtrlIndex
+  )
+{
+  ASSERT (SataCtrlIndex < MAX_SATA_CONTROLLER);
+
+  if (SataCtrlIndex == 0) {
+    return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SATA_1);
+  } else if (SataCtrlIndex == 1) {
+    return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SATA_2);
+  } else if (SataCtrlIndex == 2) {
+    return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SATA_3);
+  } else {
+    ASSERT (FALSE);
+    return 0xFF;
+  }
+}
+
+/**
+  Get SATA controller address that can be passed to the PCI Segment Library functions.
+
+  @param[in]  SataCtrlIndex       SATA controller index
+
+  @retval SATA controller address in PCI Segment Library representation
+**/
+UINT64
+SataPciCfgBase (
+  IN UINT32  SataCtrlIndex
+  )
+{
+  return PCI_SEGMENT_LIB_ADDRESS (
+           DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+           DEFAULT_PCI_BUS_NUMBER_PCH,
+           SataDevNumber (SataCtrlIndex),
+           SataFuncNumber (SataCtrlIndex),
+           0
+           );
+}
+
+/**
+  Get LPC controller PCIe Device Number
+
+  @retval LPC controller PCIe Device Number
+**/
+UINT8
+LpcDevNumber (
+  VOID
+  )
+{
+  return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_LPC);
+}
+
+/**
+  Get LPC controller PCIe Function Number
+
+  @retval LPC controller PCIe Function Number
+**/
+UINT8
+LpcFuncNumber (
+  VOID
+  )
+{
+  return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_LPC);
+}
+
+/**
+  Returns PCH LPC device PCI base address.
+
+  @retval                   PCH LPC PCI base address.
+**/
+UINT64
+LpcPciCfgBase (
+  VOID
+  )
+{
+  return PCI_SEGMENT_LIB_ADDRESS (
+           DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+           DEFAULT_PCI_BUS_NUMBER_PCH,
+           LpcDevNumber (),
+           LpcFuncNumber (),
+           0
+           );
+}
+
+/**
+  Get Thermal Device PCIe Device Number
+
+  @retval Thermal Device PCIe Device Number
+**/
+UINT8
+ThermalDevNumber (
+  VOID
+  )
+{
+  return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_THERMAL);
+}
+
+/**
+  Get Thermal Device PCIe Function Number
+
+  @retval Thermal Device PCIe Function Number
+**/
+UINT8
+ThermalFuncNumber (
+  VOID
+  )
+{
+  return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_THERMAL);
+}
+
+/**
+  Returns Thermal Device PCI base address.
+
+  @retval                   Thermal Device PCI base address.
+**/
+UINT64
+ThermalPciCfgBase (
+  VOID
+  )
+{
+  return PCI_SEGMENT_LIB_ADDRESS (
+           DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+           DEFAULT_PCI_BUS_NUMBER_PCH,
+           ThermalDevNumber (),
+           ThermalFuncNumber (),
+           0
+           );
+}
+
+/**
+  Get Serial IO I2C controller PCIe Device Number
+
+  @param[in]  I2cNumber       Serial IO I2C controller index
+
+  @retval Serial IO I2C controller PCIe Device Number
+**/
+UINT8
+SerialIoI2cDevNumber (
+  IN UINT8       I2cNumber
+  )
+{
+  if (GetPchMaxSerialIoI2cControllersNum () <= I2cNumber) {
+    ASSERT (FALSE);
+    return 0xFF;
+  }
+  switch (I2cNumber) {
+    case 0:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C0);
+    case 1:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C1);
+    case 2:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C2);
+    case 3:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C3);
+    case 4:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C4);
+    case 5:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C5);
+    case 6:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C6);
+    case 7:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C7);
+    default:
+      ASSERT (FALSE);
+      return 0xFF;
+  }
+}
+
+/**
+  Get Serial IO I2C controller PCIe Function Number
+
+  @param[in]  I2cNumber       Serial IO I2C controller index
+
+  @retval Serial IO I2C controller PCIe Function Number
+**/
+UINT8
+SerialIoI2cFuncNumber (
+  IN UINT8       I2cNumber
+  )
+{
+  if (GetPchMaxSerialIoI2cControllersNum () <= I2cNumber) {
+    ASSERT (FALSE);
+    return 0xFF;
+  }
+  switch (I2cNumber) {
+    case 0:
+      return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C0);
+    case 1:
+      return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C1);
+    case 2:
+      return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C2);
+    case 3:
+      return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C3);
+    case 4:
+      return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C4);
+    case 5:
+      return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C5);
+    case 6:
+      return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C6);
+    case 7:
+      return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C7);
+    default:
+      ASSERT (FALSE);
+      return 0xFF;
+  }
+}
+
+/**
+  Get Serial IO I2C controller address that can be passed to the PCI Segment Library functions.
+
+  @param[in]  I2cNumber       Serial IO I2C controller index
+
+  @retval Serial IO I2C controller address in PCI Segment Library representation
+**/
+UINT64
+SerialIoI2cPciCfgBase (
+  IN UINT8        I2cNumber
+  )
+{
+  return PCI_SEGMENT_LIB_ADDRESS (
+           DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+           DEFAULT_PCI_BUS_NUMBER_PCH,
+           SerialIoI2cDevNumber (I2cNumber),
+           SerialIoI2cFuncNumber (I2cNumber),
+           0
+           );
+}
+
+/**
+  Get Serial IO SPI controller PCIe Device Number
+
+  @param[in]  I2cNumber       Serial IO SPI controller index
+
+  @retval Serial IO SPI controller PCIe Device Number
+**/
+UINT8
+SerialIoSpiDevNumber (
+  IN UINT8       SpiNumber
+  )
+{
+  if (GetPchMaxSerialIoSpiControllersNum () <= SpiNumber) {
+    ASSERT (FALSE);
+    return 0xFF;
+  }
+
+  switch (SpiNumber) {
+    case 0:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI0);
+    case 1:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI1);
+    case 2:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI2);
+    case 3:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI3);
+    case 4:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI4);
+    case 5:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI5);
+    case 6:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI6);
+    default:
+      ASSERT (FALSE);
+      return 0xFF;
+  }
+}
+
+/**
+  Get Serial IO SPI controller PCIe Function Number
+
+  @param[in]  SpiNumber       Serial IO SPI controller index
+
+  @retval Serial IO SPI controller PCIe Function Number
+**/
+UINT8
+SerialIoSpiFuncNumber (
+  IN UINT8       SpiNumber
+  )
+{
+  if (GetPchMaxSerialIoSpiControllersNum () <= SpiNumber) {
+    ASSERT (FALSE);
+    return 0xFF;
+  }
+
+  switch (SpiNumber) {
+    case 0:
+      return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI0);
+    case 1:
+      return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI1);
+    case 2:
+      return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI2);
+    case 3:
+      return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI3);
+    case 4:
+      return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI4);
+    case 5:
+      return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI5);
+    case 6:
+      return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI6);
+    default:
+      ASSERT (FALSE);
+      return 0xFF;
+  }
+}
+
+/**
+  Get Serial IO SPI controller address that can be passed to the PCI Segment Library functions.
+
+  @param[in]  SpiNumber       Serial IO SPI controller index
+
+  @retval Serial IO SPI controller address in PCI Segment Library representation
+**/
+UINT64
+SerialIoSpiPciCfgBase (
+  IN UINT8        SpiNumber
+  )
+{
+  return PCI_SEGMENT_LIB_ADDRESS (
+           DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+           DEFAULT_PCI_BUS_NUMBER_PCH,
+           SerialIoSpiDevNumber (SpiNumber),
+           SerialIoSpiFuncNumber (SpiNumber),
+           0
+           );
+}
+
+/**
+  Get Serial IO UART controller PCIe Device Number
+
+  @param[in]  UartNumber       Serial IO UART controller index
+
+  @retval Serial IO UART controller PCIe Device Number
+**/
+UINT8
+SerialIoUartDevNumber (
+  IN UINT8       UartNumber
+  )
+{
+  if (GetPchMaxSerialIoUartControllersNum () <= UartNumber) {
+    ASSERT (FALSE);
+    return 0xFF;
+  }
+  switch (UartNumber) {
+    case 0:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART0);
+    case 1:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART1);
+    case 2:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART2);
+    case 3:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART3);
+    case 4:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART4);
+    case 5:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART5);
+    case 6:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART6);
+    default:
+      ASSERT (FALSE);
+      return 0xFF;
+  }
+}
+
+/**
+  Get Serial IO UART controller PCIe Function Number
+
+  @param[in]  UartNumber       Serial IO UART controller index
+
+  @retval Serial IO UART controller PCIe Function Number
+**/
+UINT8
+SerialIoUartFuncNumber (
+  IN UINT8       UartNumber
+  )
+{
+  if (GetPchMaxSerialIoUartControllersNum () <= UartNumber) {
+    ASSERT (FALSE);
+    return 0xFF;
+  }
+  switch (UartNumber) {
+    case 0:
+      return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART0);
+    case 1:
+      return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART1);
+    case 2:
+      return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART2);
+    case 3:
+      return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART3);
+    case 4:
+      return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART4);
+    case 5:
+      return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART5);
+    case 6:
+      return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART6);
+    default:
+      ASSERT (FALSE);
+      return 0xFF;
+  }
+}
+
+/**
+  Get Serial IO UART controller address that can be passed to the PCI Segment Library functions.
+
+  @param[in]  UartNumber       Serial IO UART controller index
+
+  @retval Serial IO UART controller address in PCI Segment Library representation
+**/
+UINT64
+SerialIoUartPciCfgBase (
+  IN UINT8        UartNumber
+  )
+{
+  return PCI_SEGMENT_LIB_ADDRESS (
+           DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+           DEFAULT_PCI_BUS_NUMBER_PCH,
+           SerialIoUartDevNumber (UartNumber),
+           SerialIoUartFuncNumber (UartNumber),
+           0
+           );
+}
+
+/**
+  Get PCH PCIe controller PCIe Device Number
+
+  @param[in]  RpIndex       Root port physical number. (0-based)
+
+  @retval PCH PCIe controller PCIe Device Number
+**/
+UINT8
+PchPcieRpDevNumber (
+  IN  UINTN   RpIndex
+  )
+{
+  if (RpIndex >= GetPchMaxPciePortNum ()) {
+    ASSERT (FALSE);
+    return 0xFF;
+  }
+  switch (RpIndex) {
+    case 0:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_1);
+    case 1:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_2);
+    case 2:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_3);
+    case 3:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_4);
+    case 4:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_5);
+    case 5:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_6);
+    case 6:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_7);
+    case 7:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_8);
+    case 8:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_9);
+    case 9:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_10);
+    case 10:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_11);
+    case 11:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_12);
+    case 12:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_13);
+    case 13:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_14);
+    case 14:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_15);
+    case 15:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_16);
+    case 16:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_17);
+    case 17:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_18);
+    case 18:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_19);
+    case 19:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_20);
+    case 20:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_21);
+    case 21:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_22);
+    case 22:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_23);
+    case 23:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_24);
+    case 24:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_25);
+    case 25:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_26);
+    case 26:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_27);
+    case 27:
+      return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORT_28);
+
+    default:
+      ASSERT (FALSE);
+      return 0xFF;
+  }
+}
+
+/**
+  Get PCH PCIe controller PCIe Function Number
+  Note:
+  For Client PCH generations Function Number can be various
+  depending on "Root Port Function Swapping". For such cases
+  Function Number  MUST be obtain from proper register.
+  For Server PCHs we have no "Root Port Function Swapping"
+  and we can return fixed Function Number.
+  To address this difference in this, PCH generation independent,
+  library we should call specific function in PchPcieRpLib.
+
+  @param[in]  RpIndex       Root port physical number. (0-based)
+
+  @retval PCH PCIe controller PCIe Function Number
+**/
+UINT8
+PchPcieRpFuncNumber (
+  IN  UINTN   RpIndex
+  )
+{
+  UINTN   Device;
+  UINTN   Function;
+
+  GetPchPcieRpDevFun (RpIndex, &Device, &Function);
+
+  return (UINT8)Function;
+}
+
+/**
+  Get PCH PCIe controller address that can be passed to the PCI Segment Library functions.
+
+  @param[in]  RpIndex       PCH PCIe Root Port physical number. (0-based)
+
+  @retval PCH PCIe controller address in PCI Segment Library representation
+**/
+UINT64
+PchPcieRpPciCfgBase (
+  IN  UINT32   RpIndex
+  )
+{
+  return PCI_SEGMENT_LIB_ADDRESS (
+          DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+          DEFAULT_PCI_BUS_NUMBER_PCH,
+          PchPcieRpDevNumber (RpIndex),
+          PchPcieRpFuncNumber (RpIndex),
+          0
+          );
+}
+
+/**
+  Get HECI1 PCI device number
+
+  @retval PCI dev number
+**/
+UINT8
+PchHeci1DevNumber (
+  VOID
+  )
+{
+  return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_HECI1);
+}
+
+/**
+  Get HECI1 PCI function number
+
+  @retval PCI fun number
+**/
+UINT8
+PchHeci1FuncNumber (
+  VOID
+  )
+{
+  return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_HECI1);
+}
+
+/**
+  Get HECI1 controller address that can be passed to the PCI Segment Library functions.
+
+  @retval HECI1 controller address in PCI Segment Library representation
+**/
+UINT64
+PchHeci1PciCfgBase (
+  VOID
+  )
+{
+  return PCI_SEGMENT_LIB_ADDRESS (
+            DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+            DEFAULT_PCI_BUS_NUMBER_PCH,
+            PchHeci1DevNumber (),
+            PchHeci1FuncNumber (),
+            0
+            );
+}
+
+/**
+  Get HECI3 PCI device number
+
+  @retval PCI dev number
+**/
+UINT8
+PchHeci3DevNumber (
+  VOID
+  )
+{
+  return CheckAndReturn (PCI_DEVICE_NUMBER_PCH_HECI3);
+}
+
+/**
+  Get HECI3 PCI function number
+
+  @retval PCI fun number
+**/
+UINT8
+PchHeci3FuncNumber (
+  VOID
+  )
+{
+  return CheckAndReturn (PCI_FUNCTION_NUMBER_PCH_HECI3);
+}
+
+/**
+  Get HECI3 controller address that can be passed to the PCI Segment Library functions.
+
+  @retval HECI3 controller address in PCI Segment Library representation
+**/
+UINT64
+PchHeci3PciCfgBase (
+  VOID
+  )
+{
+  return PCI_SEGMENT_LIB_ADDRESS (
+            DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+            DEFAULT_PCI_BUS_NUMBER_PCH,
+            PchHeci3DevNumber (),
+            PchHeci3FuncNumber (),
+            0
+            );
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.c
new file mode 100644
index 0000000000..2ede8e0021
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.c
@@ -0,0 +1,158 @@
+/** @file
+  System reset library services.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Uefi.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/ResetSystemLib.h>
+#include <Library/PmcLib.h>
+#include <Library/BaseLib.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/PmcRegs.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16           mBaseResetSystemABase;
+
+/**
+  Calling this function causes a system-wide reset. This sets
+  all circuitry within the system to its initial state. This type of reset
+  is asynchronous to system operation and operates without regard to
+  cycle boundaries.
+
+  System reset should not return, if it returns, it means the system does
+  not support cold reset.
+**/
+VOID
+EFIAPI
+ResetCold (
+  VOID
+  )
+{
+  IoWrite8 (R_PCH_IO_RST_CNT, V_PCH_IO_RST_CNT_FULLRESET);
+}
+
+/**
+  Calling this function causes a system-wide initialization. The processors
+  are set to their initial state, and pending cycles are not corrupted.
+
+  System reset should not return, if it returns, it means the system does
+  not support warm reset.
+**/
+VOID
+EFIAPI
+ResetWarm (
+  VOID
+  )
+{
+  IoWrite8 (R_PCH_IO_RST_CNT, V_PCH_IO_RST_CNT_HARDRESET);
+}
+
+/**
+  Calling this function causes the system to enter a power state equivalent
+  to the ACPI G2/S5 or G3 states.
+
+  System shutdown should not return, if it returns, it means the system does
+  not support shut down reset.
+**/
+VOID
+EFIAPI
+ResetShutdown (
+  VOID
+  )
+{
+  UINT16         ABase;
+  UINT32         Data32;
+
+  ABase = mBaseResetSystemABase;
+  if (ABase == 0) {
+    ABase = PmcGetAcpiBase ();
+  }
+  ///
+  /// Firstly, GPE0_EN should be disabled to avoid any GPI waking up the system from S5
+  ///
+  IoWrite32 (ABase + R_ACPI_IO_GPE0_EN_127_96, 0);
+
+  ///
+  /// Secondly, PwrSts register must be cleared
+  ///
+  /// Write a "1" to bit[8] of power button status register at
+  /// (PM_BASE + PM1_STS_OFFSET) to clear this bit
+  ///
+  IoWrite16 (ABase + R_ACPI_IO_PM1_STS, B_ACPI_IO_PM1_STS_PWRBTN);
+
+  ///
+  /// Finally, transform system into S5 sleep state
+  ///
+  Data32 = IoRead32 (ABase + R_ACPI_IO_PM1_CNT);
+
+  Data32 = (UINT32) ((Data32 &~(B_ACPI_IO_PM1_CNT_SLP_TYP + B_ACPI_IO_PM1_CNT_SLP_EN)) | V_ACPI_IO_PM1_CNT_S5);
+
+  IoWrite32 (ABase + R_ACPI_IO_PM1_CNT, Data32);
+
+  Data32 = Data32 | B_ACPI_IO_PM1_CNT_SLP_EN;
+
+  IoWrite32 (ABase + R_ACPI_IO_PM1_CNT, Data32);
+
+  return;
+}
+
+/**
+  Calling this function causes the system to enter a power state for platform specific.
+
+  @param[in] DataSize             The size of ResetData in bytes.
+  @param[in] ResetData            Optional element used to introduce a platform specific reset.
+                                  The exact type of the reset is defined by the EFI_GUID that follows
+                                  the Null-terminated Unicode string.
+
+**/
+VOID
+EFIAPI
+ResetPlatformSpecific (
+  IN UINTN            DataSize,
+  IN VOID             *ResetData OPTIONAL
+  )
+{
+  IoWrite8 (R_PCH_IO_RST_CNT, V_PCH_IO_RST_CNT_FULLRESET);
+}
+
+/**
+  Calling this function causes the system to enter a power state for capsule update.
+
+  Reset update should not return, if it returns, it means the system does
+  not support capsule update.
+
+**/
+VOID
+EFIAPI
+EnterS3WithImmediateWake (
+  VOID
+  )
+{
+  //
+  // In case there are pending capsules to process, need to flush the cache.
+  //
+  AsmWbinvd ();
+
+  ResetWarm ();
+  ASSERT (FALSE);
+}
+
+/**
+  The library constructuor.
+
+  The function does the necessary initialization work for this library instance.
+
+  @retval     EFI_SUCCESS       The function always return EFI_SUCCESS for now.
+**/
+EFI_STATUS
+EFIAPI
+BaseResetSystemLibConstructor (
+  VOID
+  )
+{
+  mBaseResetSystemABase = PmcGetAcpiBase ();
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.inf
new file mode 100644
index 0000000000..a4f805035a
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.inf
@@ -0,0 +1,38 @@
+## @file
+# Component description file for Intel Ich7 Reset System Library.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = BaseResetSystemLib
+FILE_GUID = D4FF05AA-3C7D-4B8A-A1EE-AA5EFA0B1732
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+UEFI_SPECIFICATION_VERSION = 2.00
+LIBRARY_CLASS = ResetSystemLib
+CONSTRUCTOR = BaseResetSystemLibConstructor
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[LibraryClasses]
+IoLib
+BaseLib
+DebugLib
+PmcLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+BaseResetSystemLib.c
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.c
new file mode 100644
index 0000000000..90aea8f420
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.c
@@ -0,0 +1,198 @@
+/** @file
+  This file provide services for DXE phase policy default initialization
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <ConfigBlock.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/SiConfigBlockLib.h>
+#include <Protocol/PchPolicy.h>
+#include <ScsConfig.h>
+#include <Library/DxeGpioPolicyLib.h>
+#include <Library/DxeHdaPolicyLib.h>
+#include <Library/DxePchPcieRpPolicyLib.h>
+
+/**
+  Load DXE Config block default for eMMC
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadEmmcDxeConfigDefault (
+  IN VOID          *ConfigBlockPointer
+  )
+{
+  SCS_EMMC_DXE_CONFIG  *EmmcDxeConfig;
+  EmmcDxeConfig = ConfigBlockPointer;
+
+  DEBUG ((DEBUG_INFO, "EmmcDxeConfig->Header.GuidHob.Name = %g\n", &EmmcDxeConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "EmmcDxeConfig->Header.GuidHob.Header.HobLength = 0x%x\n", EmmcDxeConfig->Header.GuidHob.Header.HobLength));
+
+  EmmcDxeConfig->DriverStrength = DriverStrength40Ohm;
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED COMPONENT_BLOCK_ENTRY  mPchDxeIpBlocks [] = {
+  {&gEmmcDxeConfigGuid,    sizeof (SCS_EMMC_DXE_CONFIG), SCS_EMMC_DXE_CONFIG_REVISION, LoadEmmcDxeConfigDefault}
+};
+
+/**
+  Print SCS_EMMC_DXE_CONFIG.
+
+  @param[in] EmmcDxeConfig         Pointer to a SCS_EMMC_DXE_CONFIG that provides the eMMC settings
+**/
+VOID
+PchPrintEmmcDxeConfig (
+  IN CONST SCS_EMMC_DXE_CONFIG  *EmmcDxeConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "------------------ PCH eMMC DXE Config ------------------\n"));
+  DEBUG ((DEBUG_INFO, " DriverStrength : %d\n", EmmcDxeConfig->DriverStrength));
+  DEBUG ((DEBUG_INFO, " EnableSoftwareHs400Tuning: %d\n", EmmcDxeConfig->EnableSoftwareHs400Tuning));
+  DEBUG ((DEBUG_INFO, " TuningLba : %X\n", EmmcDxeConfig->TuningLba));
+  DEBUG ((DEBUG_INFO, " Previous tuning success : %d\n", EmmcDxeConfig->PreviousTuningResults.TuningSuccessful));
+  if (EmmcDxeConfig->PreviousTuningResults.TuningSuccessful) {
+    DEBUG ((DEBUG_INFO, "  Hs400 Rx DLL value : %X\n", EmmcDxeConfig->PreviousTuningResults.Hs400RxValue));
+    DEBUG ((DEBUG_INFO, "  Hs400 Tx DLL value : %X\n", EmmcDxeConfig->PreviousTuningResults.Hs400TxValue));
+  }
+}
+
+/**
+  This function prints the PCH DXE phase policy.
+
+  @param[in] PchPolicy - PCH DXE Policy protocol
+**/
+VOID
+PchPrintPolicyProtocol (
+  IN  PCH_POLICY_PROTOCOL      *PchPolicy
+  )
+{
+  DEBUG_CODE_BEGIN();
+  EFI_STATUS                 Status;
+  SCS_EMMC_DXE_CONFIG        *EmmcDxeConfig;
+
+  //
+  // Get requisite IP Config Blocks which needs to be used here
+  //
+  Status = GetConfigBlock ((VOID *) PchPolicy, &gEmmcDxeConfigGuid, (VOID *)&EmmcDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "------------------------ PCH Policy (DXE) Print Start ------------------------\n"));
+  DEBUG ((DEBUG_INFO, " Revision : %x\n", PchPolicy->TableHeader.Header.Revision));
+
+  PchPrintEmmcDxeConfig (EmmcDxeConfig);
+  GpioDxePrintConfig (PchPolicy);
+  HdaDxePrintConfig (PchPolicy);
+  PchPcieRpDxePrintConfig (PchPolicy);
+
+  DEBUG ((DEBUG_INFO, "------------------------ PCH Policy (DXE) Print End --------------------------\n"));
+  DEBUG_CODE_END();
+}
+
+/**
+  CreatePchDxeConfigBlocks generates the config blocksg of PCH DXE Policy.
+  It allocates and zero out buffer, and fills in the Intel default settings.
+
+  @param[out] PchPolicy                 The pointer to get PCH DXE Protocol instance
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+CreatePchDxeConfigBlocks (
+  IN OUT  PCH_POLICY_PROTOCOL      **DxePchPolicy
+  )
+{
+  UINT16              TotalBlockSize;
+  EFI_STATUS          Status;
+  PCH_POLICY_PROTOCOL *PchPolicyInit;
+  UINT16              RequiredSize;
+
+
+  DEBUG ((DEBUG_INFO, "PCH Create Dxe Config Blocks\n"));
+
+  PchPolicyInit = NULL;
+
+  TotalBlockSize = GetComponentConfigBlockTotalSize (&mPchDxeIpBlocks[0], sizeof (mPchDxeIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+  TotalBlockSize += GpioDxeGetConfigBlockTotalSize();
+  TotalBlockSize += HdaDxeGetConfigBlockTotalSize();
+  TotalBlockSize += PchPcieRpDxeGetConfigBlockTotalSize();
+
+  DEBUG ((DEBUG_INFO, "TotalBlockSize = 0x%x\n", TotalBlockSize));
+
+  RequiredSize = sizeof (CONFIG_BLOCK_TABLE_HEADER) + TotalBlockSize;
+
+  Status = CreateConfigBlockTable (RequiredSize, (VOID *) &PchPolicyInit);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // General initialization
+  //
+  PchPolicyInit->TableHeader.Header.Revision = PCH_POLICY_PROTOCOL_REVISION;
+  //
+  // Add config blocks.
+  //
+  Status =  AddComponentConfigBlocks ((VOID *) PchPolicyInit, &mPchDxeIpBlocks[0], sizeof (mPchDxeIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+  ASSERT_EFI_ERROR (Status);
+
+  Status =  GpioDxeAddConfigBlock ((VOID *) PchPolicyInit);
+  ASSERT_EFI_ERROR (Status);
+
+  Status =  HdaDxeAddConfigBlock ((VOID *) PchPolicyInit);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = PchPcieRpDxeAddConfigBlock ((VOID *) PchPolicyInit);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Assignment for returning SaInitPolicy config block base address
+  //
+  *DxePchPolicy = PchPolicyInit;
+  return Status;
+}
+
+/**
+  PchInstallPolicyProtocol installs PCH Policy.
+  While installed, RC assumes the Policy is ready and finalized. So please update and override
+  any setting before calling this function.
+
+  @param[in] ImageHandle                Image handle of this driver.
+  @param[in] SaPolicy                   The pointer to SA Policy Protocol instance
+
+  @retval EFI_SUCCESS                   The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+PchInstallPolicyProtocol (
+  IN  EFI_HANDLE                  ImageHandle,
+  IN  PCH_POLICY_PROTOCOL         *PchPolicy
+  )
+{
+
+  EFI_STATUS            Status;
+
+  ///
+  /// Print PCH DXE Policy
+  ///
+  PchPrintPolicyProtocol (PchPolicy);
+
+  ///
+  /// Install protocol to to allow access to this Policy.
+  ///
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gPchPolicyProtocolGuid,
+                  PchPolicy,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.inf
new file mode 100644
index 0000000000..50e5cdacfd
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.inf
@@ -0,0 +1,43 @@
+## @file
+# Component description file for the PeiPchPolicy library.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxePchPolicyLib
+FILE_GUID = E2179D04-7026-48A5-9475-309CEA2F21A3
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = DxePchPolicyLib
+
+
+[LibraryClasses]
+BaseMemoryLib
+UefiBootServicesTableLib
+DebugLib
+ConfigBlockLib
+SiConfigBlockLib
+PchInfoLib
+DxeGpioPolicyLib
+DxeHdaPolicyLib
+DxePchPcieRpPolicyLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+DxePchPolicyLib.c
+
+
+[Guids]
+gEmmcDxeConfigGuid
+
+[Protocols]
+gPchPolicyProtocolGuid ## PRODUCES
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PchCycleDecodingLib.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PchCycleDecodingLib.c
new file mode 100644
index 0000000000..0927cd1ced
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PchCycleDecodingLib.c
@@ -0,0 +1,587 @@
+/** @file
+  PCH cycle decoding configuration and query library.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PchDmiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/SpiRegs.h>
+#include <Register/SmbusRegs.h>
+#include <Library/EspiLib.h>
+#include <Library/PchPciBdfLib.h>
+
+typedef enum {
+  SlaveLpcEspiCS0,
+  SlaveEspiCS1,
+  SlaveId_Max
+} SLAVE_ID_INDEX;
+
+/**
+  Get PCH TCO base address.
+
+  @param[out] Address                   Address of TCO base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid pointer passed.
+**/
+EFI_STATUS
+PchTcoBaseGet (
+  OUT UINT16                            *Address
+  )
+{
+  if (Address == NULL) {
+    DEBUG ((DEBUG_ERROR, "PchTcoBaseGet Error. Invalid pointer.\n"));
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Read "TCO Base Address" from DMI
+  // Don't read TCO base address from SMBUS PCI register since SMBUS might be disabled.
+  //
+  *Address = PchDmiGetTcoBase ();
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Set PCH LPC/eSPI and eSPI CS1# generic IO range decoding.
+
+  Steps of programming generic IO range:
+  1. Program LPC/eSPI PCI Offset 84h ~ 93h (LPC, eSPI CS0#) or A4h (eSPI CS1#) of Mask, Address, and Enable.
+  2. Program LPC/eSPI Generic IO Range in DMI
+
+  @param[in] Address                    Address for generic IO range decoding.
+  @param[in] Length                     Length of generic IO range.
+  @param[in] SlaveId                    Slave ID (refer to SLAVE_ID_INDEX)
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address or length passed.
+  @retval EFI_OUT_OF_RESOURCES          No more generic range available.
+  @retval EFI_UNSUPPORTED               DMI configuration is locked,
+                                        GenIO range conflicting with other eSPI CS
+**/
+STATIC
+EFI_STATUS
+LpcEspiGenIoRangeSetHelper (
+  IN  UINT32                            Address,
+  IN  UINT32                            Length,
+  IN  SLAVE_ID_INDEX                    SlaveId
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Set PCH LPC/eSPI generic IO range.
+  For generic IO range, the base address must align to 4 and less than 0xFFFF, and the length must be power of 2
+  and less than or equal to 256. Moreover, the address must be length aligned.
+  This function basically checks the address and length, which should not overlap with all other generic ranges.
+  If no more generic range register available, it returns out of resource error.
+  This cycle decoding is also required on DMI side
+  Some IO ranges below 0x100 have fixed target. The target might be ITSS,RTC,LPC,PMC or terminated inside P2SB
+  but all predefined and can't be changed. IO range below 0x100 will be rejected in this function except below ranges:
+    0x00-0x1F,
+    0x44-0x4B,
+    0x54-0x5F,
+    0x68-0x6F,
+    0x80-0x8F,
+    0xC0-0xFF
+  Steps of programming generic IO range:
+  1. Program LPC/eSPI PCI Offset 84h ~ 93h of Mask, Address, and Enable.
+  2. Program LPC/eSPI Generic IO Range in DMI
+
+  @param[in] Address                    Address for generic IO range base address.
+  @param[in] Length                     Length of generic IO range.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address or length passed.
+  @retval EFI_OUT_OF_RESOURCES          No more generic range available.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchLpcGenIoRangeSet (
+  IN  UINT16                            Address,
+  IN  UINTN                             Length
+  )
+{
+  return LpcEspiGenIoRangeSetHelper ((UINT32)Address, (UINT32)Length, SlaveLpcEspiCS0);
+}
+
+
+/**
+  Set PCH LPC/eSPI and eSPI CS1# memory range decoding.
+  This cycle decoding is required to be set on DMI side
+  Programming steps:
+  1. Program LPC/eSPI PCI Offset 98h (LPC, eSPI CS0#) or A8h (eSPI CS1#) [0] to [0] to disable memory decoding first before changing base address.
+  2. Program LPC/eSPI PCI Offset 98h (LPC, eSPI CS0#) or A8h (eSPI CS1#) [31:16, 0] to [Address, 1].
+  3. Program LPC/eSPI Memory Range in DMI
+
+  @param[in] Address                    Address for memory for decoding.
+  @param[in] RangeIndex                 Slave ID (refer to SLAVE_ID_INDEX)
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address or length passed.
+**/
+STATIC
+EFI_STATUS
+LpcEspiMemRangeSetHelper (
+  IN  UINT32                            Address,
+  IN  SLAVE_ID_INDEX                    SlaveId
+  )
+{
+  UINT64                                LpcBase;
+  EFI_STATUS                            Status;
+  UINT32                                GenMemReg;
+  UINT32                                MemRangeAddr;
+
+  if (((Address & (~B_LPC_CFG_LGMR_MA)) != 0) || (SlaveId >= SlaveId_Max)) {
+    DEBUG ((DEBUG_ERROR, "%a Error. Invalid Address: %x or invalid SlaveId\n", __FUNCTION__, Address));
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  LpcBase = LpcPciCfgBase ();
+
+  MemRangeAddr = ~Address;
+  if (SlaveId == SlaveEspiCS1) {
+    GenMemReg = R_ESPI_CFG_CS1GMR1;
+    // Memory Range already decoded for LPC/eSPI?
+    Status = PchLpcMemRangeGet (&MemRangeAddr);
+    if (MemRangeAddr != Address) {
+      Status = PchDmiSetEspiCs1MemRange (Address);
+      if (EFI_ERROR (Status)) {
+        ASSERT_EFI_ERROR (Status);
+        return Status;
+      }
+    }
+  } else {
+    GenMemReg = R_LPC_CFG_LGMR;
+    // Memory Range already decoded for eSPI CS1?
+    Status = PchEspiCs1MemRangeGet (&MemRangeAddr);
+    if (MemRangeAddr != Address) {
+      Status = PchDmiSetLpcMemRange (Address);
+      if (EFI_ERROR (Status)) {
+        ASSERT_EFI_ERROR (Status);
+        return Status;
+      }
+    }
+  }
+
+  //
+  // Program LPC/eSPI PCI Offset 98h (LPC, eSPI CS0#) or A8h (eSPI CS1#) [0] to [0] to disable memory decoding first before changing base address.
+  //
+  PciSegmentAnd32 (
+    LpcBase + GenMemReg,
+    (UINT32) ~B_LPC_CFG_LGMR_LMRD_EN
+    );
+  //
+  // Program LPC/eSPI PCI Offset 98h (LPC, eSPI CS0#) or A8h (eSPI CS1#) [31:16, 0] to [Address, 1].
+  //
+  PciSegmentWrite32 (
+    LpcBase + GenMemReg,
+    (Address | B_LPC_CFG_LGMR_LMRD_EN)
+    );
+
+  return Status;
+}
+
+/**
+  Set PCH LPC/eSPI memory range decoding.
+  This cycle decoding is required to be set on DMI side
+  Programming steps:
+  1. Program LPC PCI Offset 98h [0] to [0] to disable memory decoding first before changing base address.
+  2. Program LPC PCI Offset 98h [31:16, 0] to [Address, 1].
+  3. Program LPC Memory Range in DMI
+
+  @param[in] Address                    Address for memory base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address or length passed.
+  @retval EFI_OUT_OF_RESOURCES          No more generic range available.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchLpcMemRangeSet (
+  IN  UINT32                            Address
+  )
+{
+  return LpcEspiMemRangeSetHelper (Address, SlaveLpcEspiCS0);
+}
+
+/**
+  Set PCH eSPI CS1# memory range decoding.
+  This cycle decoding is required to be set on DMI side
+  Programming steps:
+  1. Program eSPI PCI Offset A8h (eSPI CS1#) [0] to [0] to disable memory decoding first before changing base address.
+  2. Program eSPI PCI Offset A8h (eSPI CS1#) [31:16, 0] to [Address, 1].
+  3. Program eSPI Memory Range in DMI
+
+  @param[in] Address                    Address for memory for decoding.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address or length passed.
+  @retval EFI_UNSUPPORTED               eSPI secondary slave not supported
+**/
+EFI_STATUS
+PchEspiCs1MemRangeSet (
+  IN  UINT32                            Address
+  )
+{
+  if (!IsEspiSecondSlaveSupported ()) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return LpcEspiMemRangeSetHelper (Address, SlaveEspiCS1);
+}
+
+/**
+  Get PCH LPC/eSPI and eSPI CS1# memory range decoding address.
+
+  @param[in]  SlaveId                   Slave ID (refer to SLAVE_ID_INDEX)
+  @param[out] Address                   Address of LPC/eSPI or eSPI CS1# memory decoding base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+  @retval EFI_UNSUPPORTED               eSPI secondary slave not supported
+**/
+STATIC
+EFI_STATUS
+LpcEspiMemRangeGetHelper (
+  IN  SLAVE_ID_INDEX                    SlaveId,
+  OUT UINT32                            *Address
+  )
+{
+  UINT32                                GenMemReg;
+
+  if ((Address == NULL) || (SlaveId >= SlaveId_Max)) {
+    DEBUG ((DEBUG_ERROR, "%a Error. Invalid pointer or SlaveId.\n", __FUNCTION__));
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (SlaveId == SlaveEspiCS1) {
+    GenMemReg = R_ESPI_CFG_CS1GMR1;
+  } else {
+    GenMemReg = R_LPC_CFG_LGMR;
+  }
+  *Address = PciSegmentRead32 (LpcPciCfgBase () + GenMemReg) & B_LPC_CFG_LGMR_MA;
+  return EFI_SUCCESS;
+}
+
+/**
+  Get PCH LPC/eSPI memory range decoding address.
+
+  @param[out] Address                   Address of LPC/eSPI memory decoding base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+**/
+EFI_STATUS
+PchLpcMemRangeGet (
+  OUT UINT32                            *Address
+  )
+{
+  return LpcEspiMemRangeGetHelper (SlaveLpcEspiCS0, Address);
+}
+
+/**
+  Get PCH eSPI CS1# memory range decoding address.
+
+  @param[out] Address                   Address of eSPI CS1# memory decoding base address.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid base address passed.
+  @retval EFI_UNSUPPORTED               eSPI secondary slave not supported
+**/
+EFI_STATUS
+PchEspiCs1MemRangeGet (
+  OUT UINT32                            *Address
+  )
+{
+  if (!IsEspiSecondSlaveSupported ()) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return LpcEspiMemRangeGetHelper (SlaveEspiCS1, Address);
+}
+
+/**
+  Set PCH BIOS range deocding.
+  This will check General Control and Status bit 10 (GCS.BBS) to identify SPI or LPC/eSPI and program BDE register accordingly.
+  Please check EDS for detail of BiosDecodeEnable bit definition.
+    bit 15: F8-FF Enable
+    bit 14: F0-F8 Enable
+    bit 13: E8-EF Enable
+    bit 12: E0-E8 Enable
+    bit 11: D8-DF Enable
+    bit 10: D0-D7 Enable
+    bit  9: C8-CF Enable
+    bit  8: C0-C7 Enable
+    bit  7: Legacy F Segment Enable
+    bit  6: Legacy E Segment Enable
+    bit  5: Reserved
+    bit  4: Reserved
+    bit  3: 70-7F Enable
+    bit  2: 60-6F Enable
+    bit  1: 50-5F Enable
+    bit  0: 40-4F Enable
+  This cycle decoding is also required in DMI
+  Programming steps:
+  1. if GCS.BBS is 0 (SPI), program SPI offset D8h to BiosDecodeEnable.
+     if GCS.BBS is 1 (LPC/eSPi), program LPC offset D8h to BiosDecodeEnable.
+  2. program LPC BIOS Decode Enable in DMI
+
+  @param[in] BiosDecodeEnable           Bios decode enable setting.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchBiosDecodeEnableSet (
+  IN  UINT16                            BiosDecodeEnable
+  )
+{
+  UINT64                                BaseAddr;
+  EFI_STATUS                            Status;
+
+  Status = PchDmiSetBiosDecodeEnable (BiosDecodeEnable);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  //
+  // Check Boot BIOS Strap in DMI
+  //
+  if (PchDmiIsBootBiosStrapSetForSpi ()) {
+    BaseAddr = SpiPciCfgBase ();
+    //
+    // If SPI, Program SPI offset D8h to BiosDecodeEnable.
+    //
+    PciSegmentWrite16 (BaseAddr + R_SPI_CFG_BDE, BiosDecodeEnable);
+  } else {
+    BaseAddr = LpcPciCfgBase ();
+    //
+    // If LPC/eSPi, program LPC offset D8h to BiosDecodeEnable.
+    //
+    PciSegmentWrite16 (BaseAddr + R_LPC_CFG_BDE, BiosDecodeEnable);
+  }
+
+  return Status;
+}
+
+/**
+  Set PCH LPC/eSPI IO decode ranges.
+  Program LPC/eSPI I/O Decode Ranges in DMI to the same value programmed in LPC/eSPI PCI offset 80h.
+  Please check EDS for detail of LPC/eSPI IO decode ranges bit definition.
+  Bit  12: FDD range
+  Bit 9:8: LPT range
+  Bit 6:4: ComB range
+  Bit 2:0: ComA range
+
+  @param[in] LpcIoDecodeRanges          LPC/eSPI IO decode ranges bit settings.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchLpcIoDecodeRangesSet (
+  IN  UINT16                            LpcIoDecodeRanges
+  )
+{
+  UINT64                                LpcBaseAddr;
+  EFI_STATUS                            Status;
+
+  //
+  // Note: Inside this function, don't use debug print since it's could used before debug print ready.
+  //
+
+  LpcBaseAddr = LpcPciCfgBase ();
+
+  //
+  // check if setting is identical
+  //
+  if (LpcIoDecodeRanges == PciSegmentRead16 (LpcBaseAddr + R_LPC_CFG_IOD)) {
+    return EFI_SUCCESS;
+  }
+
+  Status = PchDmiSetLpcIoDecodeRanges (LpcIoDecodeRanges);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  //
+  // program LPC/eSPI PCI offset 80h.
+  //
+  PciSegmentWrite16 (LpcBaseAddr + R_LPC_CFG_IOD, LpcIoDecodeRanges);
+
+  return Status;
+}
+
+/**
+  Set PCH LPC/eSPI and eSPI CS1# IO enable decoding.
+  Setup I/O Enables in DMI to the same value program in LPC/eSPI PCI offset 82h (LPC, eSPI CS0#) or A0h (eSPI CS1#).
+  Note: Bit[15:10] of the source decode register is Read-Only. The IO range indicated by the Enables field
+  in LPC/eSPI PCI offset 82h[13:10] or A0h[13:10] is always forwarded by DMI to subtractive agent for handling.
+  Please check EDS for detail of Lpc/eSPI IO decode ranges bit definition.
+
+  @param[in] IoEnableDecoding           LPC/eSPI IO enable decoding bit settings.
+  @param[in] SlaveId                    Slave ID (refer to SLAVE_ID_INDEX)
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMI configuration is locked
+**/
+EFI_STATUS
+LpcEspiIoEnableDecodingSetHelper (
+  IN  UINT16                            IoEnableDecoding,
+  IN  SLAVE_ID_INDEX                    SlaveId
+  )
+{
+  UINT64      LpcBaseAddr;
+  EFI_STATUS  Status;
+  UINT16      Cs1IoEnableDecodingOrg;
+  UINT16      Cs0IoEnableDecodingOrg;
+  UINT16      IoEnableDecodingMerged;
+
+  LpcBaseAddr = LpcPciCfgBase ();
+
+  Cs0IoEnableDecodingOrg = PciSegmentRead16 (LpcBaseAddr + R_LPC_CFG_IOE);
+
+  if (IsEspiSecondSlaveSupported ()) {
+    Cs1IoEnableDecodingOrg = PciSegmentRead16 (LpcBaseAddr + R_ESPI_CFG_CS1IORE);
+  } else {
+    Cs1IoEnableDecodingOrg = 0;
+  }
+
+  if (SlaveId == SlaveEspiCS1) {
+    if (IoEnableDecoding == Cs1IoEnableDecodingOrg) {
+      return EFI_SUCCESS;
+    } else {
+      IoEnableDecodingMerged = (Cs0IoEnableDecodingOrg | IoEnableDecoding);
+    }
+  } else {
+    if ((IoEnableDecoding | Cs1IoEnableDecodingOrg) == Cs0IoEnableDecodingOrg) {
+      return EFI_SUCCESS;
+    } else {
+      IoEnableDecodingMerged = (Cs1IoEnableDecodingOrg | IoEnableDecoding);
+    }
+  }
+
+  Status = PchDmiSetLpcIoEnable (IoEnableDecodingMerged);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  //
+  // program PCI offset 82h for LPC/eSPI.
+  //
+  PciSegmentWrite16 (LpcBaseAddr + R_LPC_CFG_IOE, IoEnableDecodingMerged);
+
+  if (SlaveId == SlaveEspiCS1) {
+    //
+    // For eSPI CS1# device program eSPI PCI offset A0h.
+    //
+    PciSegmentWrite16 (LpcBaseAddr + R_ESPI_CFG_CS1IORE, IoEnableDecoding);
+  }
+
+  return Status;
+}
+
+/**
+  Set PCH LPC and eSPI CS0# IO enable decoding.
+  Setup I/O Enables in DMI to the same value program in LPC/eSPI PCI offset 82h.
+  Note: Bit[15:10] of the source decode register is Read-Only. The IO range indicated by the Enables field
+  in LPC/eSPI PCI offset 82h[13:10] is always forwarded by DMI to subtractive agent for handling.
+  Please check EDS for detail of LPC/eSPI IO decode ranges bit definition.
+
+  @param[in] LpcIoEnableDecoding        LPC IO enable decoding bit settings.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMIC.SRL is set.
+**/
+EFI_STATUS
+PchLpcIoEnableDecodingSet (
+  IN  UINT16                            LpcIoEnableDecoding
+  )
+{
+  return LpcEspiIoEnableDecodingSetHelper (LpcIoEnableDecoding, SlaveLpcEspiCS0);
+}
+
+/**
+  Set PCH eSPI CS1# IO enable decoding.
+  Setup I/O Enables in DMI to the same value program in eSPI PCI offset A0h (eSPI CS1#).
+  Note: Bit[15:10] of the source decode register is Read-Only. The IO range indicated by the Enables field
+  in eSPI PCI offset A0h[13:10] is always forwarded by DMI to subtractive agent for handling.
+  Please check EDS for detail of eSPI IO decode ranges bit definition.
+
+  @param[in] IoEnableDecoding           eSPI IO enable decoding bit settings.
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_UNSUPPORTED               DMI configuration is locked
+**/
+EFI_STATUS
+PchEspiCs1IoEnableDecodingSet (
+  IN  UINT16                            IoEnableDecoding
+  )
+{
+  if (!IsEspiSecondSlaveSupported ()) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return LpcEspiIoEnableDecodingSetHelper (IoEnableDecoding, SlaveEspiCS1);
+}
+
+
+/**
+  Get IO APIC regsiters base address.
+
+  @param[out] IoApicBase                Buffer of IO APIC regsiter address
+
+  @retval EFI_SUCCESS                   Successfully completed.
+**/
+EFI_STATUS
+PchIoApicBaseGet (
+  OUT UINT32                            *IoApicBase
+  )
+{
+  *IoApicBase = PcdGet32 (PcdSiIoApicBaseAddress);
+  return EFI_SUCCESS;
+}
+
+/**
+  Get HPET base address.
+
+  @param[out] HpetBase                  Buffer of HPET base address
+
+  @retval EFI_SUCCESS                   Successfully completed.
+  @retval EFI_INVALID_PARAMETER         Invalid offset passed.
+**/
+EFI_STATUS
+PchHpetBaseGet (
+  OUT UINT32                            *HpetBase
+  )
+{
+  if (HpetBase == NULL) {
+    DEBUG ((DEBUG_ERROR, "PchHpetBaseGet Error. Invalid pointer.\n"));
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *HpetBase = PcdGet32 (PcdSiHpetBaseAddress);
+  return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PeiDxeSmmPchCycleDecodingLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PeiDxeSmmPchCycleDecodingLib.inf
new file mode 100644
index 0000000000..ea6b434f29
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PeiDxeSmmPchCycleDecodingLib.inf
@@ -0,0 +1,42 @@
+## @file
+# PCH cycle decoding 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 = PeiDxeSmmPchCycleDecodingLib
+FILE_GUID = 676C749F-9CD1-46B7-BAFD-4B1BC36B4C8E
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchCycleDecodingLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PciSegmentLib
+PchInfoLib
+PchPcrLib
+PchDmiLib
+EspiLib
+PchPciBdfLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Sources]
+PchCycleDecodingLib.c
+
+[Pcd]
+gSiPkgTokenSpaceGuid.PcdSiHpetBaseAddress        ## CONSUMES
+gSiPkgTokenSpaceGuid.PcdSiIoApicBaseAddress      ## CONSUMES
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLib.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLib.c
new file mode 100644
index 0000000000..df8a23d5a3
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLib.c
@@ -0,0 +1,127 @@
+/** @file
+  Pch information library.
+
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PrintLib.h>
+#include <Library/PcdLib.h>
+#include "PchInfoLibPrivate.h"
+#include <Register/PchRegs.h>
+#include <Register/PchRegsLpc.h>
+#include <PchPcieRpInfo.h>
+#include <IndustryStandard/Pci30.h>
+#include <Library/PchPciBdfLib.h>
+
+/**
+  Return Pch Series
+
+  @retval PCH_SERIES            Pch Series
+**/
+PCH_SERIES
+PchSeries (
+  VOID
+  )
+{
+  return PCH_LP;
+}
+
+/**
+  Return Pch stepping type
+
+  @retval PCH_STEPPING            Pch stepping type
+**/
+PCH_STEPPING
+PchStepping (
+  VOID
+  )
+{
+  return 0;
+}
+
+/**
+  Check if this is TGL PCH generation
+
+  @retval TRUE                It's TGL PCH
+  @retval FALSE               It's not TGL PCH
+**/
+BOOLEAN
+IsTglPch (
+  VOID
+  )
+{
+  return (PchGeneration () == TGL_PCH);
+}
+
+/**
+  Get PCH stepping ASCII string.
+  Function determines major and minor stepping versions and writes them into a buffer.
+  The return string is zero terminated
+
+  @param [out]     Buffer               Output buffer of string
+  @param [in]      BufferSize           Buffer size.
+                                        Must not be less then PCH_STEPPING_STR_LENGTH_MAX
+
+  @retval EFI_SUCCESS                   String copied successfully
+  @retval EFI_INVALID_PARAMETER         The stepping is not supported, or parameters are NULL
+  @retval EFI_BUFFER_TOO_SMALL          Input buffer size is too small
+**/
+EFI_STATUS
+PchGetSteppingStr (
+  OUT    CHAR8                          *Buffer,
+  IN     UINT32                         BufferSize
+  )
+{
+  PCH_STEPPING PchStep;
+
+  PchStep = PchStepping ();
+
+  if ((Buffer == NULL) || (BufferSize == 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+  if (BufferSize < PCH_STEPPING_STR_LENGTH_MAX) {
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  PchPrintSteppingStr (Buffer, BufferSize, PchStep);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Get Pch Maximum Pcie Controller Number
+
+  @retval Pch Maximum Pcie Root Port Number
+**/
+UINT8
+GetPchMaxPcieControllerNum (
+  VOID
+  )
+{
+  return GetPchMaxPciePortNum () / PCH_PCIE_CONTROLLER_PORTS;
+}
+
+/**
+  return support status for P2SB PCR 20-bit addressing
+
+  @retval    TRUE
+  @retval    FALSE
+**/
+BOOLEAN
+IsP2sb20bPcrSupported (
+  VOID
+  )
+{
+  return FALSE;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibPrivate.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibPrivate.h
new file mode 100644
index 0000000000..a93c3dbafd
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibPrivate.h
@@ -0,0 +1,58 @@
+/** @file
+  Private header for PCH Info 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
+**/
+
+/**
+  Structure for PCH SKU string mapping
+**/
+struct PCH_SKU_STRING {
+  UINT16        Id;
+  CHAR8         *String;
+};
+
+/**
+  Determine Pch Series based on Device Id
+
+  @param[in] LpcDeviceId      Lpc Device Id
+
+  @retval PCH_SERIES          Pch Series
+**/
+PCH_SERIES
+PchSeriesFromLpcDid (
+  IN UINT16 LpcDeviceId
+  );
+
+/**
+Determine Pch Generation based on Device Id
+
+@param[in] LpcDeviceId            Lpc Device Id
+
+@retval PCH_GENERATION            Pch Generation
+**/
+PCH_GENERATION
+PchGenerationFromDid (
+  IN UINT16 LpcDeviceId
+  );
+
+/**
+  Print Pch Stepping String
+
+  @param[out] Buffer         Output buffer of string
+  @param[in]  BufferSize     Buffer Size
+  @param[in]  PchStep        Pch Stepping Type
+
+  @retval VOID
+**/
+VOID
+PchPrintSteppingStr (
+  OUT CHAR8        *Buffer,
+  IN  UINT32       BufferSize,
+  IN  PCH_STEPPING PchStep
+  );
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibTgl.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibTgl.c
new file mode 100644
index 0000000000..bb3c7975e8
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInfoLibTgl.c
@@ -0,0 +1,715 @@
+/** @file
+  Pch information library for TGL.
+
+  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 <Uefi/UefiBaseType.h>
+#include <Library/PchInfoLib.h>
+#include "PchInfoLibPrivate.h"
+#include <Library/PrintLib.h>
+#include <Register/PchRegsLpc.h>
+
+/**
+  Print Pch Stepping String
+
+  @param[out] Buffer         Output buffer of string
+  @param[in]  BufferSize     Buffer Size
+  @param[in]  PchStep        Pch Stepping Type
+
+  @retval VOID
+**/
+VOID
+PchPrintSteppingStr (
+  OUT CHAR8        *Buffer,
+  IN  UINT32       BufferSize,
+  IN  PCH_STEPPING PchStep
+  )
+{
+  AsciiSPrint (Buffer, BufferSize, "%c%c", 'A' + (PchStep >> 4), '0' + (PchStep & 0xF));
+}
+
+/**
+  Return Pch Generation
+
+  @retval PCH_GENERATION      Pch Generation
+**/
+PCH_GENERATION
+PchGeneration (
+  VOID
+  )
+{
+  return TGL_PCH;
+}
+
+
+/**
+  Get PCH series ASCII string.
+
+  @retval PCH Series string
+**/
+CHAR8*
+PchGetSeriesStr (
+  VOID
+  )
+{
+  switch (PchSeries ()) {
+
+    case PCH_LP:
+      return "TGL PCH-LP";
+
+    default:
+      return NULL;
+  }
+}
+
+/**
+  Get Pch Maximum Pcie Clock Number
+
+  @retval Pch Maximum Pcie Clock Number
+**/
+UINT8
+GetPchMaxPcieClockNum (
+  VOID
+  )
+{
+  return 7;
+}
+
+/**
+  Get Pch Maximum Pcie ClockReq Number
+
+  @retval Pch Maximum Pcie ClockReq Number
+**/
+UINT8
+GetPchMaxPcieClockReqNum (
+  VOID
+  )
+{
+  return GetPchMaxPcieClockNum ();
+}
+
+/**
+  Get Pch Maximum Type C Port Number
+
+  @retval Pch Maximum Type C Port Number
+**/
+UINT8
+GetPchMaxTypeCPortNum (
+  VOID
+  )
+{
+  switch (PchSeries ()) {
+    case PCH_LP:
+      return 4;
+    default:
+      return 0;
+  }
+}
+
+/**
+  Check whether integrated LAN controller is supported by PCH Series.
+
+  @retval TRUE                    GbE is supported in current PCH
+  @retval FALSE                   GbE is not supported on current PCH
+**/
+BOOLEAN
+PchIsGbeSupported (
+  VOID
+  )
+{
+  return TRUE;
+}
+
+/**
+  Check whether integrated TSN is supported by PCH Series.
+
+  @retval TRUE                    TSN is supported in current PCH
+  @retval FALSE                   TSN is not supported on current PCH
+**/
+BOOLEAN
+PchIsTsnSupported (
+  VOID
+  )
+{
+#if FixedPcdGet8(PcdEmbeddedEnable) == 0x1
+  return TRUE;
+#else
+  return FALSE;
+#endif
+}
+
+/**
+  Check whether ISH is supported by PCH Series.
+
+  @retval TRUE                    ISH is supported in current PCH
+  @retval FALSE                   ISH is not supported on current PCH
+**/
+BOOLEAN
+PchIsIshSupported (
+  VOID
+  )
+{
+  return TRUE;
+}
+
+/**
+  Get Pch Maximum Pcie Root Port Number
+
+  @retval Pch Maximum Pcie Root Port Number
+**/
+UINT8
+GetPchMaxPciePortNum (
+  VOID
+  )
+{
+  switch (PchSeries ()) {
+    case PCH_LP:
+      return 12;
+    default:
+      return 0;
+  }
+}
+
+/**
+  Get Pch Maximum Hda Dmic Link
+
+  @retval Pch Maximum Hda Dmic Link
+**/
+UINT8
+GetPchHdaMaxDmicLinkNum (
+  VOID
+  )
+{
+  return 2;
+}
+
+/**
+  Get Pch Maximum Hda Sndw Link
+
+  @retval Pch Maximum Hda Sndw Link
+**/
+UINT8
+GetPchHdaMaxSndwLinkNum (
+  VOID
+  )
+{
+  return 4;
+}
+
+/**
+  Get Pch Maximum Hda Ssp Link
+
+  @retval Pch Maximum Hda Ssp Link
+**/
+UINT8
+GetPchHdaMaxSspLinkNum (
+  VOID
+  )
+{
+  return 3;
+}
+
+/**
+  Check if given Audio Interface is supported
+
+  @param[in] AudioLinkType   Link type support to be checked
+  @param[in] AudioLinkIndex  Link number
+
+  @retval    TRUE           Link supported
+  @retval    FALSE          Link not supported
+**/
+BOOLEAN
+IsAudioInterfaceSupported (
+  IN HDAUDIO_LINK_TYPE     AudioLinkType,
+  IN UINT32                AudioLinkIndex
+  )
+{
+  //
+  // Interfaces supported:
+  // 1. HDA Link (SDI0/SDI1)
+  // 2. Display Audio Link (SDI2)
+  // 3. SSP[0-5]
+  // 4. SNDW[1-4]
+  //
+  switch (AudioLinkType) {
+    case HdaLink:
+    case HdaIDispLink:
+      return TRUE;
+    case HdaDmic:
+      if (AudioLinkIndex < 2) {
+        return TRUE;
+      } else {
+        return FALSE;
+      }
+    case HdaSsp:
+      if (AudioLinkIndex < 6) {
+        return TRUE;
+      } else {
+        return FALSE;
+      }
+    case HdaSndw:
+      if (AudioLinkIndex < 1) {
+        return TRUE;
+      } else if (AudioLinkIndex < 4) {
+        return TRUE;
+      } else {
+        return FALSE;
+      }
+    default:
+      return FALSE;
+  }
+}
+
+/**
+  Check if given Display Audio Link T-Mode is supported
+
+  @param[in] Tmode          T-mode support to be checked
+
+  @retval    TRUE           T-mode supported
+  @retval    FALSE          T-mode not supported
+**/
+BOOLEAN
+IsAudioIDispTmodeSupported (
+  IN HDAUDIO_IDISP_TMODE Tmode
+  )
+{
+  //
+  // iDisplay Audio Link T-mode support per PCH Generation/Series:
+  // 1. 2T  - TGL-LP/H/N
+  // 2. 4T  - TGL-LP (default), TGL-H, TGL-N
+  // 3. 8T  - TGL-H, TGL-N (default)
+  // 4. 16T - TGL-H, TGL-N (not-POR)
+  //
+  switch (Tmode) {
+    case HdaIDispMode1T:
+      return FALSE;
+    case HdaIDispMode2T:
+    case HdaIDispMode4T:
+    case HdaIDispMode8T:
+      return TRUE;
+    case HdaIDispMode16T:
+      return FALSE;
+    default:
+      return FALSE;
+  }
+}
+
+/**
+Get Pch Usb2 Maximum Physical Port Number
+
+@retval Pch Usb2 Maximum Physical Port Number
+**/
+UINT8
+GetPchUsb2MaxPhysicalPortNum(
+  VOID
+  )
+{
+  switch (PchSeries()) {
+    case PCH_LP:
+      return 10;
+    default:
+      return 0;
+  }
+}
+
+/**
+Get Pch Maximum Usb2 Port Number of XHCI Controller
+
+@retval Pch Maximum Usb2 Port Number of XHCI Controller
+**/
+UINT8
+GetPchXhciMaxUsb2PortNum(
+  VOID
+  )
+{
+  switch (PchSeries()) {
+    case PCH_LP:
+      return 12;
+    default:
+      return 0;
+  }
+}
+
+/**
+Get Pch Maximum Usb3 Port Number of XHCI Controller
+
+@retval Pch Maximum Usb3 Port Number of XHCI Controller
+**/
+UINT8
+GetPchXhciMaxUsb3PortNum(
+  VOID
+  )
+{
+  switch (PchSeries()) {
+    case PCH_LP:
+      return 4;
+    default:
+      return 0;
+  }
+}
+
+/**
+  Gets the maximum number of UFS controller supported by this chipset.
+
+  @return Number of supported UFS controllers
+**/
+UINT8
+PchGetMaxUfsNum (
+  VOID
+  )
+{
+  return 2;
+}
+
+/**
+  Check if this chipset supports eMMC controller
+
+  @retval BOOLEAN  TRUE if supported, FALSE otherwise
+**/
+BOOLEAN
+IsPchEmmcSupported (
+  VOID
+  )
+{
+  return FALSE;
+}
+
+/**
+  Check if this chipset supports SD controller
+
+  @retval BOOLEAN  TRUE if supported, FALSE otherwise
+**/
+BOOLEAN
+IsPchSdCardSupported (
+  VOID
+  )
+{
+  return FALSE;
+}
+
+/**
+  Check if this chipset supports THC controller
+
+  @retval BOOLEAN  TRUE if supported, FALSE otherwise
+**/
+BOOLEAN
+IsPchThcSupported (
+  VOID
+  )
+{
+  return TRUE;
+}
+
+/**
+  Check if this chipset supports HSIO BIOS Sync
+
+  @retval BOOLEAN  TRUE if supported, FALSE otherwise
+**/
+BOOLEAN
+IsPchChipsetInitSyncSupported (
+  VOID
+  )
+{
+  return TRUE;
+}
+
+/**
+  Check if link between PCH and CPU is an P-DMI
+
+  @retval    TRUE           P-DMI link
+  @retval    FALSE          Not an P-DMI link
+**/
+BOOLEAN
+IsPchWithPdmi (
+  VOID
+  )
+{
+  return FALSE;
+}
+
+/**
+  Check whether ATX Shutdown (PS_ON) is supported.
+
+  @retval    TRUE           ATX Shutdown (PS_ON) is supported in PCH
+  @retval    FALSE          ATX Shutdown (PS_ON) is not supported by PCH
+**/
+BOOLEAN
+IsPchPSOnSupported (
+  VOID
+  )
+{
+  return FALSE;
+}
+
+/**
+  Check if link between PCH and CPU is an OP-DMI
+
+  @retval    TRUE           OP-DMI link
+  @retval    FALSE          Not an OP-DMI link
+**/
+BOOLEAN
+IsPchWithOpdmi (
+  VOID
+  )
+{
+  return TRUE;
+}
+
+/**
+  Check if link between PCH and CPU is an F-DMI
+
+  @retval    TRUE           F-DMI link
+  @retval    FALSE          Not an F-DMI link
+**/
+BOOLEAN
+IsPchWithFdmi (
+  VOID
+  )
+{
+  return FALSE;
+}
+/**
+  Get Pch Maximum ISH UART Controller number
+
+  @retval Pch Maximum ISH UART controllers number
+**/
+UINT8
+GetPchMaxIshUartControllersNum (
+  VOID
+  )
+{
+  return 2;
+}
+
+/**
+  Get Pch Maximum ISH I2C Controller number
+
+  @retval Pch Maximum ISH I2C controllers number
+**/
+UINT8
+GetPchMaxIshI2cControllersNum (
+  VOID
+  )
+{
+  return 3;
+}
+
+/**
+  Get Pch Maximum ISH I3C Controller number
+
+  @retval Pch Maximum ISH I3C controllers number
+**/
+UINT8
+GetPchMaxIshI3cControllersNum (
+  VOID
+  )
+{
+  return 0;
+}
+
+/**
+  Get Pch Maximum ISH SPI Controller number
+
+  @retval Pch Maximum ISH SPI controllers number
+**/
+UINT8
+GetPchMaxIshSpiControllersNum (
+  VOID
+  )
+{
+  return 1;
+}
+
+/**
+  Get Pch Maximum ISH SPI Controller Cs pins number
+
+  @retval Pch Maximum ISH SPI controller Cs pins number
+**/
+UINT8
+GetPchMaxIshSpiControllerCsPinsNum (
+  VOID
+  )
+{
+  return 1;
+}
+
+/**
+  Get Pch Maximum ISH GP number
+
+  @retval Pch Maximum ISH GP number
+**/
+UINT8
+GetPchMaxIshGpNum (
+  VOID
+  )
+{
+  return 8;
+}
+
+/**
+  Get Pch Maximum Serial IO I2C controllers number
+
+  @retval Pch Maximum Serial IO I2C controllers number
+**/
+UINT8
+GetPchMaxSerialIoI2cControllersNum (
+  VOID
+  )
+{
+  return 6;
+}
+
+/**
+  Get Pch Maximum Serial IO SPI controllers number
+
+  @retval Pch Maximum Serial IO SPI controllers number
+**/
+UINT8
+GetPchMaxSerialIoSpiControllersNum (
+  VOID
+  )
+{
+  return 4;
+}
+
+/**
+  Get Pch Maximum Serial IO UART controllers number
+
+  @retval Pch Maximum Serial IO UART controllers number
+**/
+UINT8
+GetPchMaxSerialIoUartControllersNum (
+  VOID
+  )
+{
+  return 4;
+}
+
+/**
+  Get Pch Maximum Serial IO SPI Chip Selects count
+
+  @retval Pch Maximum Serial IO SPI Chip Selects number
+**/
+UINT8
+GetPchMaxSerialIoSpiChipSelectsNum (
+  VOID
+  )
+{
+  return 2;
+}
+
+/**
+  Get Pch Maximum ME Applet count
+
+  @retval Pch Maximum ME Applet number
+**/
+UINT8
+GetPchMaxMeAppletCount (
+  VOID
+  )
+{
+  return 31;
+}
+
+/**
+  Get Pch Maximum ME Session count
+
+  @retval Pch Maximum ME Sesion number
+**/
+UINT8
+GetPchMaxMeSessionCount (
+  VOID
+  )
+{
+  return 16;
+}
+
+/**
+  Get Pch Maximum THC count
+
+  @retval Pch Maximum THC count number
+**/
+UINT8
+GetPchMaxThcCount (
+  VOID
+  )
+{
+  return 2;
+}
+
+/**
+  Returns a frequency of the sosc_clk signal.
+  All SATA controllers on the system are assumed to
+  work on the same sosc_clk frequency.
+
+  @retval Frequency of the sosc_clk signal.
+**/
+SATA_SOSC_CLK_FREQ
+GetSataSoscClkFreq (
+  VOID
+  )
+{
+  return SataSosc100Mhz;
+}
+
+/**
+  Check if SATA support should be awake after function disable
+
+  @retval    TRUE
+  @retval    FALSE
+**/
+BOOLEAN
+IsSataSupportWakeAfterFunctionDisable (
+  VOID
+  )
+{
+  return TRUE;
+}
+
+/**
+  Returns USB2 PHY Reference Clock frequency value used by PCH
+  This defines what electrical tuning parameters shall be used
+  during USB2 PHY initialization programming
+
+  @retval Frequency reference clock for USB2 PHY
+**/
+USB2_PHY_REF_FREQ
+GetUsb2PhyRefFreq (
+  VOID
+  )
+{
+  return FREQ_19_2;
+}
+
+/**
+  Check if SPI in a given PCH generation supports an Extended BIOS Range Decode
+
+  @retval TRUE or FALSE if PCH supports Extended BIOS Range Decode
+**/
+BOOLEAN
+IsExtendedBiosRangeDecodeSupported (
+  VOID
+  )
+{
+  return TRUE;
+}
+
+#define SPI_PCH_LP_DMI_TARGET   0x23A8
+
+/**
+  Returns DMI target for current PCH SPI
+
+  @retval PCH SPI DMI target value
+**/
+UINT16
+GetPchSpiDmiTarget (
+  VOID
+  )
+{
+  return SPI_PCH_LP_DMI_TARGET;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PeiDxeSmmPchInfoLibTgl.inf b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PeiDxeSmmPchInfoLibTgl.inf
new file mode 100644
index 0000000000..4b3fb988d2
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PeiDxeSmmPchInfoLibTgl.inf
@@ -0,0 +1,43 @@
+## @file
+# PCH information library for TigerLake PCH.
+#
+# 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 = PeiDxeSmmPchInfoLibTgl
+FILE_GUID = 253B9BFC-026F-4BB4-AC2C-AC167BC0F43C
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PchInfoLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PrintLib
+PciSegmentLib
+PchPcrLib
+PcdLib
+PchPciBdfLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchInfoLib.c
+PchInfoLibTgl.c
+
+[Pcd]
+gSiPkgTokenSpaceGuid.PcdEmbeddedEnable                        ## CONSUMES
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 33/40] TigerlakeSiliconPkg/Pch: Add Pch private library instances
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (30 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 32/40] TigerlakeSiliconPkg/Pch: Add Pch " Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 34/40] TigerlakeSiliconPkg/SystemAgent: Add Acpi Tables and " Heng Luo
                   ` (6 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * Pch/LibraryPrivate/BaseSiScheduleResetLib
  * Pch/LibraryPrivate/SmmPchPrivateLib

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/Pch/LibraryPrivate/BaseSiScheduleResetLib/BaseSiScheduleResetLib.c   | 171 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/LibraryPrivate/BaseSiScheduleResetLib/BaseSiScheduleResetLib.inf |  37 +++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/LibraryPrivate/SmmPchPrivateLib/SmmPchPrivateLib.c               |  57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/LibraryPrivate/SmmPchPrivateLib/SmmPchPrivateLib.inf             |  31 +++++++++++++++++++++++++++++++
 4 files changed, 296 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/LibraryPrivate/BaseSiScheduleResetLib/BaseSiScheduleResetLib.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/LibraryPrivate/BaseSiScheduleResetLib/BaseSiScheduleResetLib.c
new file mode 100644
index 0000000000..1880244a01
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/LibraryPrivate/BaseSiScheduleResetLib/BaseSiScheduleResetLib.c
@@ -0,0 +1,171 @@
+/** @file
+  Reset scheduling library services
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Library/DebugLib.h>
+#include <Library/ResetSystemLib.h>
+#include <Uefi/UefiBaseType.h>
+#include <Uefi.h>
+#include <Pi/PiMultiPhase.h>
+#include <Library/HobLib.h>
+#include <PchResetPlatformSpecific.h>
+#include <Library/SiScheduleResetLib.h>
+#include <SiScheduleResetHob.h>
+
+/**
+  This function returns SiScheduleResetHob for library use
+**/
+STATIC
+SI_SCHEDULE_RESET_HOB *
+SiScheduleGetResetData (
+  VOID
+  )
+{
+  STATIC SI_SCHEDULE_RESET_HOB *SiScheduleResetHob = NULL;
+  SI_SCHEDULE_RESET_HOB        *SiScheduleResetHobTemp;
+  VOID                         *HobPtr;
+
+  if (SiScheduleResetHob != NULL) {
+    return SiScheduleResetHob;
+  }
+
+  HobPtr = GetFirstGuidHob (&gSiScheduleResetHobGuid);
+  if (HobPtr == NULL) {
+    SiScheduleResetHobTemp = BuildGuidHob (&gSiScheduleResetHobGuid, sizeof (SI_SCHEDULE_RESET_HOB));
+    if (SiScheduleResetHobTemp == NULL) {
+      ASSERT (FALSE);
+      return SiScheduleResetHobTemp;
+    }
+    SiScheduleResetHobTemp->ResetType = 0xFF;
+    DEBUG ((DEBUG_INFO, "SiScheduleResetSetType : Init SiScheduleResetHob\n"));
+  } else {
+    SiScheduleResetHobTemp = (SI_SCHEDULE_RESET_HOB*) GET_GUID_HOB_DATA (HobPtr);
+  }
+  SiScheduleResetHob = SiScheduleResetHobTemp;
+  return SiScheduleResetHobTemp;
+}
+
+/**
+  This function updates the reset information in SiScheduleResetHob
+  @param[in] ResetType        UEFI defined reset type.
+  @param[in] ResetData        Optional element used to introduce a platform specific reset.
+                               The exact type of the reset is defined by the EFI_GUID that follows
+                               the Null-terminated Unicode string.
+**/
+VOID
+SiScheduleResetSetType (
+  IN EFI_RESET_TYPE     ResetType,
+  IN PCH_RESET_DATA     *ResetData OPTIONAL
+  )
+{
+  SI_SCHEDULE_RESET_HOB *SiScheduleResetHob;
+  if (ResetType > EfiResetPlatformSpecific) {
+    DEBUG ((DEBUG_INFO, "Unsupported Reset Type Requested\n"));
+    return;
+  }
+  SiScheduleResetHob = SiScheduleGetResetData ();
+  if (SiScheduleResetHob == NULL) {
+    return;
+  }
+  DEBUG ((DEBUG_INFO, "SiScheduleResetSetType : Current Reset Type = 0x%x\n", SiScheduleResetHob->ResetType));
+  if (SiScheduleResetHob->ResetType == ResetType) {
+    DEBUG ((DEBUG_INFO, "Current Reset Type is same as requested Reset Type\n"));
+    return;
+  }
+  if (SiScheduleResetHob->ResetType == 0xFF) {
+    // Init Reset Type to lowest ResetType
+    SiScheduleResetHob->ResetType = EfiResetWarm;
+  }
+  //
+  // ResetType Priority set as : ResetPlatformSpecific(3) > ResetShutdown(2) > ResetCold(0) > ResetWarm(1)
+  //
+  switch (ResetType) {
+    case EfiResetWarm:
+      break;
+
+    case EfiResetCold:
+      if (SiScheduleResetHob->ResetType == EfiResetWarm) {
+        SiScheduleResetHob->ResetType = ResetType;
+      }
+      break;
+
+    case EfiResetShutdown:
+      if (SiScheduleResetHob->ResetType < ResetType)
+      SiScheduleResetHob->ResetType = ResetType;
+      break;
+
+    case EfiResetPlatformSpecific:
+      SiScheduleResetHob->ResetType = ResetType;
+      SiScheduleResetHob->ResetData = *ResetData;
+      break;
+  }
+  DEBUG ((DEBUG_INFO, "SiScheduleResetSetType : New Reset Type = 0x%x\n", SiScheduleResetHob->ResetType));
+}
+
+/**
+  This function returns TRUE or FALSE depending on whether a reset is required based on SiScheduleResetHob
+
+  @retval     BOOLEAN       The function returns FALSE if no reset is required
+**/
+BOOLEAN
+SiScheduleResetIsRequired (
+  VOID
+  )
+{
+  VOID                  *HobPtr;
+
+  HobPtr = NULL;
+  HobPtr = GetFirstGuidHob (&gSiScheduleResetHobGuid);
+  if (HobPtr == NULL) {
+    return FALSE;
+  }
+  return TRUE;
+}
+
+/**
+  This function performs reset based on SiScheduleResetHob
+
+  @retval     BOOLEAN       The function returns FALSE if no reset is required
+**/
+BOOLEAN
+SiScheduleResetPerformReset (
+  VOID
+  )
+{
+  UINTN                 DataSize;
+  SI_SCHEDULE_RESET_HOB *SiScheduleResetHob;
+
+  if (!SiScheduleResetIsRequired ()) {
+    return FALSE;
+  }
+  SiScheduleResetHob = SiScheduleGetResetData ();
+
+  if (SiScheduleResetHob == NULL) {
+    return TRUE;
+  }
+
+  DEBUG ((DEBUG_INFO, "SiScheduleResetPerformReset : Reset Type = 0x%x\n", SiScheduleResetHob->ResetType));
+  switch (SiScheduleResetHob->ResetType) {
+  case EfiResetWarm:
+    ResetWarm ();
+    break;
+
+  case EfiResetCold:
+    ResetCold ();
+    break;
+
+  case EfiResetShutdown:
+    ResetShutdown ();
+    break;
+
+  case EfiResetPlatformSpecific:
+    DataSize = sizeof (PCH_RESET_DATA);
+    ResetPlatformSpecific (DataSize, &SiScheduleResetHob->ResetData);
+    break;
+  }
+  // Code should never reach here
+  ASSERT (FALSE);
+  return TRUE;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/LibraryPrivate/BaseSiScheduleResetLib/BaseSiScheduleResetLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/Pch/LibraryPrivate/BaseSiScheduleResetLib/BaseSiScheduleResetLib.inf
new file mode 100644
index 0000000000..4363a752a9
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/LibraryPrivate/BaseSiScheduleResetLib/BaseSiScheduleResetLib.inf
@@ -0,0 +1,37 @@
+## @file
+# Component description file for Si Reset Schedule Library.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = BaseSiScheduleResetLib
+FILE_GUID = E6F3D551-36C0-4737-80C7-47FC57593163
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = SiScheduleResetLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+HobLib
+ResetSystemLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Guids]
+gSiScheduleResetHobGuid
+
+[Sources]
+BaseSiScheduleResetLib.c
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/LibraryPrivate/SmmPchPrivateLib/SmmPchPrivateLib.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/LibraryPrivate/SmmPchPrivateLib/SmmPchPrivateLib.c
new file mode 100644
index 0000000000..46cf735860
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/LibraryPrivate/SmmPchPrivateLib/SmmPchPrivateLib.c
@@ -0,0 +1,57 @@
+/** @file
+  PCH SMM private lib.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi/UefiBaseType.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Register/CommonMsr.h>
+
+/**
+  Set InSmm.Sts bit
+**/
+VOID
+PchSetInSmmSts (
+  VOID
+  )
+{
+  UINT32      Data32;
+
+
+  ///
+  /// Read memory location FED30880h OR with 00000001h, place the result in EAX,
+  /// and write data to lower 32 bits of MSR 1FEh (sample code available)
+  ///
+  Data32 = MmioRead32 (0xFED30880);
+  AsmWriteMsr32 (MSR_SPCL_CHIPSET_USAGE, Data32 | BIT0);
+  ///
+  /// Read FED30880h back to ensure the setting went through.
+  ///
+  Data32 = MmioRead32 (0xFED30880);
+}
+
+/**
+  Clear InSmm.Sts bit
+**/
+VOID
+PchClearInSmmSts (
+  VOID
+  )
+{
+  UINT32      Data32;
+
+  ///
+  /// Read memory location FED30880h AND with FFFFFFFEh, place the result in EAX,
+  /// and write data to lower 32 bits of MSR 1FEh (sample code available)
+  ///
+  Data32 = MmioRead32 (0xFED30880);
+  AsmWriteMsr32 (MSR_SPCL_CHIPSET_USAGE, Data32 & (UINT32) (~BIT0));
+  ///
+  /// Read FED30880h back to ensure the setting went through.
+  ///
+  Data32 = MmioRead32 (0xFED30880);
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/LibraryPrivate/SmmPchPrivateLib/SmmPchPrivateLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/Pch/LibraryPrivate/SmmPchPrivateLib/SmmPchPrivateLib.inf
new file mode 100644
index 0000000000..6d4c3a5729
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/LibraryPrivate/SmmPchPrivateLib/SmmPchPrivateLib.inf
@@ -0,0 +1,31 @@
+## @file
+#  PCH SMM private lib.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = SmmPchPrivateLib
+FILE_GUID = FE6495FB-7AA9-4A24-BF3E-4698F7BCE0EE
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_SMM_DRIVER
+LIBRARY_CLASS = SmmPchPrivateLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+SmmPchPrivateLib.c
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 34/40] TigerlakeSiliconPkg/SystemAgent: Add Acpi Tables and library instances
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (31 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 33/40] TigerlakeSiliconPkg/Pch: Add Pch private " Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 35/40] TigerlakeSiliconPkg/Fru/TglCpu: Add CpuPcieRp and Vtd " Heng Luo
                   ` (5 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * SystemAgent/AcpiTables
  * SystemAgent/Library/DxeSaPolicyLib
  * SystemAgent/Library/PeiDxeSmmSaPlatformLib

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/CpuPcieRp.asl                           |  252 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/CpuPcieRpCommon.asl                     |  289 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/PegCommon.asl                           | 1344 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/PegRtd3.asl                             |  124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl                                  |   26 ++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl                              |   20 ++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf                              |   22 +++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.c                   |  254 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf                 |   48 ++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLibrary.h               |   33 ++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/PeiDxeSmmSaPlatformLib.inf |   32 ++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.c        |   68 +++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.h        |   21 ++++++++++++++
 13 files changed, 2533 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/CpuPcieRp.asl b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/CpuPcieRp.asl
new file mode 100644
index 0000000000..0babf047ed
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/CpuPcieRp.asl
@@ -0,0 +1,252 @@
+/** @file
+  This file contains the CPU PCIe Root Port configuration
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+External(LTRX) // CPU PCIe Root Port 0 Latency Tolerance Reporting Enable
+External(LTRY) // CPU PCIe Root Port 1 Latency Tolerance Reporting Enable
+External(LTRZ) // CPU PCIe Root Port 2 Latency Tolerance Reporting Enable
+External(LTRW) // CPU PCIe Root Port 3 Latency Tolerance Reporting Enable
+External(SMSL) // CPU PCIe Root Port Latency Tolerance Reporting Max Snoop Latency
+External(SNSL) // CPU PCIe Root Port Latency Tolerance Reporting Max No Snoop Latency
+External(PG0E) // CpuPcieRp0Enable <b>0: Disable</b>; 1: Enable
+External(PG1E) // CpuPcieRp1Enable <b>0: Disable</b>; 1: Enable
+External(PG2E) // CpuPcieRp2Enable <b>0: Disable</b>; 1: Enable
+External(PG3E) // CpuPcieRp3Enable <b>0: Disable</b>; 1: Enable
+External(\_SB.PC00.PEG0, DeviceObj)
+External(\_SB.PC00.PEG1, DeviceObj)
+External(\_SB.PC00.PEG2, DeviceObj)
+External(\_SB.PC00.PEG3, DeviceObj)
+External(\_SB.PC00.PEG0.PEGP, DeviceObj)
+External(\_SB.PC00.PEG1.PEGP, DeviceObj)
+External(\_SB.PC00.PEG2.PEGP, DeviceObj)
+External(\_SB.PC00.PEG3.PEGP, DeviceObj)
+External(\AR02)
+External(\PD02)
+External(\AR0A)
+External(\PD0A)
+External(\AR0B)
+External(\PD0B)
+External(\AR0C)
+External(\PD0C)
+External(VMDE)
+External(VMCP)
+External(MPGN)
+External(PBR1)
+External(PBR2)
+External(PBR3)
+
+Scope (\_SB.PC00.PEG0) {
+
+  Name(SLOT, 0) // CPU PCIe root port index 0 corresponds to PEG60 (0/6/0)
+
+  Method (_STA, 0x0, NotSerialized) {
+    if(PG0E == 1) { // If CPU PCIe RP0 enabled?
+      Return(0x0F)
+    }
+    Return(0x00)
+  }
+
+  Name(LTEN, 0)
+  Name(LMSL, 0)
+  Name(LNSL, 0)
+
+  Method(_INI)
+  {
+    Store (LTRX, LTEN)
+    Store (SMSL, LMSL)
+    Store (SNSL, LNSL)
+    If(LAnd(CondRefOf(VMCP),CondRefOf(VMDE))) {
+      If(LAnd(LEqual(VMDE,1),LNotEqual(And(VMCP,0x8),0))) {
+        Store (1, CPMV)
+      }
+    }
+  }
+
+  Method(_PRT,0) {
+    If(PICM) {
+      Return(AR02)
+    } // APIC mode
+    Return (PD02) // PIC Mode
+  } // end _PRT
+
+  Include("CpuPcieRpCommon.asl")
+} // PEG0 scope end
+
+Scope (\_SB.PC00.PEG1) {
+
+  Name(SLOT, 1) // CPU PCIe root port index 1 corresponds to PEG10 (0/1/0)
+
+  Method (_STA, 0x0, NotSerialized) {
+    if(PG1E == 1) { // If CPU PCIe RP1 enabled?
+      Return(0x0F)
+    }
+    Return(0x00)
+  }
+
+  Name(LTEN, 0)
+  Name(LMSL, 0)
+  Name(LNSL, 0)
+
+  Method(_INI)
+  {
+    Store (LTRY, LTEN)
+    Store (SMSL, LMSL)
+    Store (SNSL, LNSL)
+    If(LAnd(CondRefOf(VMCP),CondRefOf(VMDE))) {
+      If(LAnd(LEqual(VMDE,1),LNotEqual(And(VMCP,0x1),0))) {
+        Store (1, CPMV)
+      }
+    }
+  }
+
+  Method(_PRT,0) {
+    If(PICM) {
+      Return(AR0A)
+    } // APIC mode
+    Return (PD0A) // PIC Mode
+  } // end _PRT
+
+  Include("CpuPcieRpCommon.asl")
+} // PEG1 scope end
+
+Scope (\_SB.PC00.PEG2) {
+
+  Name(SLOT, 2) // CPU PCIe root port index 2 corresponds to PEG11 (0/1/1)
+
+  Method (_STA, 0x0, NotSerialized) {
+    if(PG2E == 1) { // If CPU PCIe RP2 enabled?
+      Return(0x0F)
+    }
+    Return(0x00)
+  }
+
+  Name(LTEN, 0)
+  Name(LMSL, 0)
+  Name(LNSL, 0)
+
+  Method(_INI)
+  {
+    Store (LTRZ, LTEN)
+    Store (SMSL, LMSL)
+    Store (SNSL, LNSL)
+    If(LAnd(CondRefOf(VMCP),CondRefOf(VMDE))) {
+      If(LAnd(LEqual(VMDE,1),LNotEqual(And(VMCP,0x2),0))) {
+        Store (1, CPMV)
+      }
+    }
+  }
+
+  Method(_PRT,0) {
+    If(PICM) {
+      Return(AR0B)
+    } // APIC mode
+    Return (PD0B) // PIC Mode
+  } // end _PRT
+
+  Include("CpuPcieRpCommon.asl")
+} // PEG2 scope end
+
+If (CondRefOf(\_SB.PC00.PEG3)) {
+  Scope (\_SB.PC00.PEG3) {
+
+    Name(SLOT, 3) // CPU PCIe root port index 3 corresponds to PEG12 (0/1/2)
+
+    Method (_STA, 0x0, NotSerialized) {
+      if(PG3E == 1) { // If CPU PCIe RP3 enabled?
+        Return(0x0F)
+      }
+      Return(0x00)
+    }
+
+    Name(LTEN, 0)
+    Name(LMSL, 0)
+    Name(LNSL, 0)
+
+    Method(_INI)
+    {
+      Store (LTRW, LTEN)
+      Store (SMSL, LMSL)
+      Store (SNSL, LNSL)
+      If(LAnd(CondRefOf(VMCP),CondRefOf(VMDE))) {
+        If(LAnd(LEqual(VMDE,1),LNotEqual(And(VMCP,0x4),0))) {
+          Store (1, CPMV)
+        }
+      }
+    }
+
+    Method(_PRT,0) {
+      If(PICM) {
+        Return(AR0C)
+      } // APIC mode
+      Return (PD0C) // PIC Mode
+    } // end _PRT
+
+    Include("CpuPcieRpCommon.asl")
+  } // PEG3 scope end
+}
+
+Scope(\_SB.PC00.PEG0.PEGP) {
+  Method(_PRW, 0) {
+    Return(GPRW(0x69, 4)) // can wakeup from S4 state
+  }
+}
+
+
+If (PBR1) {
+  Scope(\_SB.PC00.PEG1.PEGP) {
+    Method(_S0W, 0) { Return(4)} //D3cold is supported
+
+    Device (PEGD) {
+      Method(_S0W, 0) { Return(4)} //D3cold is supported
+      Name(_ADR, 0x00000000)
+      Method(_PRW, 0) { Return(GPRW(0x69, 4)) } // can wakeup from S4 state
+    }
+  } // end "P.E.G. Port Slot x16"
+}
+
+Scope(\_SB.PC00.PEG1.PEGP) {
+  Method(_PRW, 0) {
+    Return(GPRW(0x69, 4)) // can wakeup from S4 state
+  }
+}
+
+
+If (PBR2) {
+  Scope(\_SB.PC00.PEG2.PEGP) {
+    Method(_S0W, 0) { Return(4)} //D3cold is supported
+
+    Device (PEGD) {
+      Method(_S0W, 0) { Return(4)} //D3cold is supported
+      Name(_ADR, 0x00000000)
+      Method(_PRW, 0) { Return(GPRW(0x69, 4)) } // can wakeup from S4 state
+    }
+  } // end "P.E.G. Port Slot 2x8"
+}
+
+Scope(\_SB.PC00.PEG2.PEGP) {
+  Method(_PRW, 0) {
+    Return(GPRW(0x69, 4)) // can wakeup from S4 state
+  }
+}
+
+If (PBR3) {
+  Scope(\_SB.PC00.PEG3.PEGP) {
+    Method(_S0W, 0) { Return(4)} //D3cold is supported
+
+    Device (PEGD) {
+      Method(_S0W, 0) { Return(4)} //D3cold is supported
+      Name(_ADR, 0x00000000)
+      Method(_PRW, 0) { Return(GPRW(0x69, 4)) } // can wakeup from S4 state
+    }
+  } // end "P.E.G. Port Slot 1x8 - 2x4"
+}
+
+If (CondRefOf(\_SB.PC00.PEG3)) {
+  Scope(\_SB.PC00.PEG3.PEGP) {
+    Method(_PRW, 0) {
+      Return(GPRW(0x69, 4)) // can wakeup from S4 state
+    }
+  }
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/CpuPcieRpCommon.asl b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/CpuPcieRpCommon.asl
new file mode 100644
index 0000000000..81f785dfc5
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/CpuPcieRpCommon.asl
@@ -0,0 +1,289 @@
+/** @file
+  This file contains the CPU PCIe Root Port configuration
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+  External(ECR1)
+  External(GPRW, MethodObj)
+  External(PICM)
+  External(\_SB.PC00.PC2M, MethodObj)
+  External(_ADR, IntObj)
+
+
+  OperationRegion(PXCS,SystemMemory,\_SB.PC00.PC2M(_ADR),0x480)
+  Field(PXCS, AnyAcc, NoLock, Preserve)
+  {
+    Offset(0),
+    VDID, 32,
+    Offset(0x50), // LCTL - Link Control Register
+    L0SE, 1,      // 0, L0s Entry Enabled
+    , 3,
+    LDIS, 1,
+    , 3,
+    Offset(0x52), // LSTS - Link Status Register
+    , 13,
+    LASX, 1,      // 0, Link Active Status
+    Offset(0x5A), // SLSTS[7:0] - Slot Status Register
+    ABPX, 1,      // 0, Attention Button Pressed
+    , 2,
+    PDCX, 1,      // 3, Presence Detect Changed
+    , 2,
+    PDSX, 1,      // 6, Presence Detect State
+    , 1,
+    Offset(0x60), // RSTS - Root Status Register
+    , 16,
+    PSPX, 1,      // 16,  PME Status
+    Offset(0xA4),
+    D3HT, 2,      // Power State
+    Offset(0xD8), // 0xD8, MPC - Miscellaneous Port Configuration Register
+    , 30,
+    HPEX, 1,      // 30,  Hot Plug SCI Enable
+    PMEX, 1,      // 31,  Power Management SCI Enable
+    Offset(0xE0), // 0xE0, SPR - Scratch Pad Register
+    , 0,
+    SCB0, 1,      // Sticky Scratch Pad Bit SCB0
+    Offset(0xE2), // 0xE2, RPPGEN - Root Port Power Gating Enable
+    , 2,
+    L23E, 1,       // 2,   L23_Rdy Entry Request (L23ER)
+    L23R, 1,       // 3,   L23_Rdy to Detect Transition (L23R2DT)
+    Offset(0x324), // 0x324 - PCIEDBG
+    , 3,
+    LEDM, 1,       // PCIEDBG.DMIL1EDM
+    Offset(0x328), // 0x328 - PCIESTS1
+    , 24,
+    LTSM, 8,
+  }
+  Field(PXCS,AnyAcc, NoLock, WriteAsZeros)
+  {
+    Offset(0xDC), // 0xDC, SMSCS - SMI/SCI Status Register
+    , 30,
+    HPSX, 1,      // 30,  Hot Plug SCI Status
+    PMSX, 1       // 31,  Power Management SCI Status
+  }
+
+  //
+  // L23D method recovers link from L2 or L3 state. Used for RTD3 flows, right after endpoint is powered up and exits reset.
+  // This flow is implemented in ASL because rootport registers used for L2/L3 entry/exit
+  // are proprietary and OS drivers don't know about them.
+  //
+  Method (L23D, 0, Serialized) {
+    If(LNotEqual(SCB0,0x1)) {
+      Return()
+    }
+
+    /// Set L23_Rdy to Detect Transition  (L23R2DT)
+    Store(1, L23R)
+    Store(0, Local0)
+    /// Wait for transition to Detect
+    While(L23R) {
+      If(Lgreater(Local0, 4))
+      {
+        Break
+      }
+      Sleep(16)
+      Increment(Local0)
+    }
+    Store(0,SCB0)
+
+    /// Once in Detect, wait up to 124 ms for Link Active (typically happens in under 70ms)
+    /// Worst case per PCIe spec from Detect to Link Active is:
+    /// 24ms in Detect (12+12), 72ms in Polling (24+48), 28ms in Config (24+2+2+2+2)
+    Store(0, Local0)
+    While(LEqual(LASX,0)) {
+      If(Lgreater(Local0, 8))
+      {
+        Break
+      }
+      Sleep(16)
+      Increment(Local0)
+    }
+  }
+
+  //
+  // DL23 method puts link to L2 or L3 state. Used for RTD3 flows, before endpoint is powered down.
+  // This flow is implemented in ASL because rootport registers used for L2/L3 entry/exit
+  // are proprietary and OS drivers don't know about them.
+  //
+  Method (DL23, 0, Serialized) {
+    Store(1, L23E)
+    Sleep(16)
+    Store(0, Local0)
+    While(L23E) {
+      If(Lgreater(Local0, 4))
+      {
+        Break
+      }
+      Sleep(16)
+      Increment(Local0)
+    }
+    Store(1,SCB0)
+  }
+
+  Name(LTRV, Package(){0,0,0,0})
+  Name(CPMV, 0) // CPU Rp Mapped under VMD
+
+  //
+  // _DSM Device Specific Method
+  //
+  // Arg0: UUID Unique function identifier
+  // Arg1: Integer Revision Level
+  // Arg2: Integer Function Index (0 = Return Supported Functions)
+  // Arg3: Package Parameters
+  Method(_DSM, 4, Serialized) {
+    //
+    // Switch based on which unique function identifier was passed in
+    //
+    If (LEqual(Arg0, ToUUID ("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
+      //
+      // _DSM Definitions for Latency Tolerance Reporting
+      //
+      // Arguments:
+      // Arg0: UUID: E5C937D0-3553-4d7a-9117-EA4D19C3434D
+      // Arg1: Revision ID: 3
+      // Arg2: Function Index: 0, 6, 8, 9
+      // Arg3: Empty Package
+      //
+      // Switch by function index
+      //
+      Switch(ToInteger(Arg2)) {
+        //
+        // Function Index:0
+        // Standard query - A bitmask of functions supported
+        //
+        Case (0) {
+          Name(OPTS,Buffer(2){0,0})
+          CreateBitField(OPTS,0,FUN0)
+          CreateBitField(OPTS,6,FUN6)
+          CreateBitField(OPTS,8,FUN8)
+          CreateBitField(OPTS,9,FUN9)
+
+          Store(1,FUN0)
+          if(LEqual(LTEN,1)) {
+            Store(1,Fun6)
+          }
+
+          If (LGreaterEqual(Arg1, 2)){ // test Arg1 for Revision ID: 2
+            If(CondRefOf(ECR1)) {
+              if(LEqual(ECR1,1)){
+                if (LGreaterEqual(Arg1, 3)){ // test Arg1 for Revision ID: 3
+                  Store(1,Fun8)
+                  Store(1,Fun9)
+                }
+              }
+            }
+          }
+          Return (OPTS)
+        }
+
+        //
+        // Function Index: 6
+        // LTR Extended Capability Structure
+        //
+        Case(6) {
+          if (LGreaterEqual(Arg1, 2)){ // test Arg1 for Revision ID: 2
+            Store(And(ShiftRight(LMSL,10),7), Index(LTRV, 0))
+            Store(And(LMSL,0x3FF), Index(LTRV, 1))
+            Store(And(ShiftRight(LNSL,10),7), Index(LTRV, 2))
+            Store(And(LNSL,0x3FF), Index(LTRV, 3))
+            Return (LTRV)
+          }
+        }
+        Case(8) { //ECR ACPI additions for FW latency optimizations, DSM for Avoiding Power-On Reset Delay Duplication on Sx Resume
+          If(CondRefOf(ECR1)) {
+            if(LEqual(ECR1,1)){
+              if (LGreaterEqual(Arg1, 3)) { // test Arg1 for Revision ID: 3
+                return (1)
+              }
+            }
+          }
+        }
+        Case(9) { //ECR ACPI additions for FW latency optimizations, DSM for Specifying Device Readiness Durations
+          If(CondRefOf(ECR1)) {
+            if(LEqual(ECR1,1)){
+              if (LGreaterEqual(Arg1, 3)) { // test Arg1 for Revision ID: 3
+                return(Package(5){50000,Ones,Ones,50000,Ones})
+              }
+            }
+          }
+        }
+      } // End of switch(Arg2)
+    } // End of if
+    return (Buffer() {0x00})
+  } // End of _DSM
+
+  Method(_PRW, 0) {
+    Return(GPRW(0x69, 4)) // can wakeup from S4 state
+  }
+
+  Method(_PS0,0,Serialized)
+  {
+    If (LEqual(HPEX, 1)) {
+      Store(0, HPEX) // Disable Hot Plug SCI
+      Store(1, HPSX) // Clear Hot Plug SCI status
+    }
+    If (LEqual (PMEX, 1)) {
+      Store(0, PMEX) // Disable Power Management SCI
+      Store(1, PMSX) // Clear Power Management SCI status
+    }
+  }
+  Method(_PS3,0,Serialized)
+  {
+    If (LEqual (HPEX, 0)) {
+      Store(1, HPEX) // Enable Hot Plug SCI
+      Store(1, HPSX) // Clear Hot Plug SCI status
+    }
+    If (LEqual(PMEX, 0)) {
+      Store(1, PMEX) // Enable Power Management SCI
+      Store(1, PMSX) // Clear Power Management SCI status
+    }
+  }
+
+  Method (_DSD, 0) {
+    Return (
+      Package () {
+        ToUUID("FDF06FAD-F744-4451-BB64-ECD792215B10"),
+        Package () {
+          Package (2) {"FundamentalDeviceResetTriggeredOnD3ToD0", 1},
+        }
+      }
+    ) // End of Return ()
+  }
+
+  //
+  // PCI_EXP_STS Handler for PCIE Root Port
+  //
+  Method(HPME,0,Serialized) {
+    If(LAnd(LNotEqual(VDID,0xFFFFFFFF), LEqual(PMSX,1))) { //if port exists and has PME SCI Status set...
+      Store(1,PMSX) // clear rootport's PME SCI status
+      Store(1,PSPX) // consume one pending PME status to prevent it from blocking the queue
+      Return(0x01)
+    }
+    Return(0x00)
+  }
+
+  //
+  // Sub-Method of _L61 Hot-Plug event
+  // _L61 event handler should invoke this method to support HotPlug wake event from PEG RP
+  //
+  Method(HPEV,0,Serialized) {
+    If(LAnd(LNotEqual(VDID,0xFFFFFFFF), HPSX)) {
+      // Clear HotPlug SCI event status
+      Store(1, HPSX)
+
+      If(LEqual(PDCX, 1)) {
+        // Clear Presence Detect Changed
+        Store(1,PDCX)
+
+        If(LEqual(PDSX, 0)) {
+          // The PCI Express slot is empty, so disable L0s on hot unplug
+          //
+          Store(0,L0SE)
+        }
+        // Perform proper notification
+        // to the OS.
+        Notify(^,0)
+      }
+    }
+  }
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/PegCommon.asl b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/PegCommon.asl
new file mode 100644
index 0000000000..68b10309d4
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/PegCommon.asl
@@ -0,0 +1,1344 @@
+/** @file
+  This file contains the device definitions of the SystemAgent
+  PCIE ACPI Reference Code.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+External(\_SB.ISME, MethodObj)
+External(\_SB.SHPO, MethodObj)
+External(\_SB.CAGS, MethodObj)
+External(\_SB.GGOV, MethodObj)
+External(\_SB.SGOV, MethodObj)
+External(\_SB.PC00.PEG0, DeviceObj)
+External(\_SB.PC00.PEG1, DeviceObj)
+External(\_SB.PC00.PEG2, DeviceObj)
+External(\_SB.PC00.PEG3, DeviceObj)
+External(\_SB.PC00.PEG0.PPRW, MethodObj)
+External(\_SB.PC00.PEG1.PPRW, MethodObj)
+External(\_SB.PC00.PEG2.PPRW, MethodObj)
+External(\_SB.PC00.PEG3.PPRW, MethodObj)
+External(\_SB.PC00.PC2M, MethodObj)
+External(P8XH, MethodObj)
+External(SPCO, MethodObj)
+External(PINI, MethodObj) // Platform specific PCIe root port initialization
+External(PRES, MethodObj)
+External(GPRW, MethodObj)
+External(\SLOT)
+External(\P0WK)
+External(\P1WK)
+External(\P2WK)
+External(\P3WK)
+External(\XBAS)
+External(\SBN0)
+External(\SBN1)
+External(\SBN2)
+External(\SBN3)
+External(\EECP)
+External(\EEC1)
+External(\EEC2)
+External(\EEC3)
+External(\SGGP)
+External(\HRE0)
+External(\HRG0)
+External(\HRA0)
+External(\PWE0)
+External(\PWG0)
+External(\PWA0)
+External(\P1GP)
+External(\HRE1)
+External(\HRG1)
+External(\HRA1)
+External(\PWE1)
+External(\PWG1)
+External(\PWA1)
+External(\P2GP)
+External(\HRE2)
+External(\HRG2)
+External(\HRA2)
+External(\PWE2)
+External(\PWG2)
+External(\PWA2)
+External(\P3GP)
+External(\HRE3)
+External(\HRG3)
+External(\HRA3)
+External(\PWE3)
+External(\PWG3)
+External(\PWA3)
+External(\P0SC)
+External(\P1SC)
+External(\P2SC)
+External(\P3SC)
+External(\DLPW)
+External(\DLHR)
+External(\OBFX)
+External(\OBFY)
+External(\OBFZ)
+External(\OBFA)
+External(\OSYS)
+
+//GPE Event handling - Start
+Scope(\_GPE) {
+  //
+  // _L6F Method call for PEG0/1/2/3 ports to handle 2-tier RTD3 GPE events
+  //
+  Method(P0L6,0)
+  {
+    // PEG0 Device Wake Event
+    If (\_SB.ISME(P0WK))
+    {
+      \_SB.SHPO(P0WK, 1)             // set gpio ownership to driver(0=ACPI mode, 1=GPIO mode)
+      Notify(\_SB.PC00.PEG0, 0x02)   // device wake
+      \_SB.CAGS(P0WK)                // Clear GPE status bit for PEG0 WAKE
+    }
+  }
+
+  Method(P1L6,0)
+  {
+    // PEG1 Device Wake Event
+    If (\_SB.ISME(P1WK))
+    {
+      \_SB.SHPO(P1WK, 1)             // set gpio ownership to driver(0=ACPI mode, 1=GPIO mode)
+      Notify(\_SB.PC00.PEG1, 0x02)   // device wake
+      \_SB.CAGS(P1WK)                // Clear GPE status bit for PEG1 WAKE
+    }
+  }
+
+  Method(P2L6,0)
+  {
+    // PEG2 Device Wake Event
+    If (\_SB.ISME(P2WK))
+    {
+      \_SB.SHPO(P2WK, 1)             // set gpio ownership to driver(0=ACPI mode, 1=GPIO mode)
+      Notify(\_SB.PC00.PEG2, 0x02)   // device wake
+      \_SB.CAGS(P2WK)                // Clear GPE status bit for PEG2 WAKE
+    }
+  }
+
+  If (CondRefOf(\_SB.PC00.PEG3)) {
+    Method(P3L6,0)
+    {
+      // PEG2 Device Wake Event
+      If (\_SB.ISME(P3WK))
+      {
+        \_SB.SHPO(P3WK, 1)             // set gpio ownership to driver(0=ACPI mode, 1=GPIO mode)
+        Notify(\_SB.PC00.PEG3, 0x02)   // device wake
+        \_SB.CAGS(P3WK)                // Clear GPE status bit for PEG2 WAKE
+      }
+    }
+  }
+} //Scope(\_GPE)
+
+If(LAnd((LEqual(HGMD,2)), (LEqual(HGST,1)))) {
+///
+/// P.E.G. Root Port D6F0
+///
+Scope(\_SB.PC00.PEG0) {
+  Name(WKEN, 0)
+
+  PowerResource(PG00, 0, 0) {
+    Name(_STA, One)
+    Method(_ON, 0, Serialized) {
+      If(LGreater(OSYS,2009)) {
+        PGON(0)
+        Store(One, _STA)
+      }
+    }
+    Method(_OFF, 0, Serialized) {
+      If(LGreater(OSYS,2009)) {
+        PGOF(0)
+        Store(Zero, _STA)
+      }
+    }
+  } //End of PowerResource(PG00, 0, 0)
+
+  Name(_PR0,Package(){PG00})
+  Name(_PR3,Package(){PG00})
+
+  ///
+  /// This method is used to enable/disable wake from PEG60 (WKEN)
+  ///
+  Method(_DSW, 3)
+  {
+    If(Arg1)
+    {
+      Store(0, WKEN)        /// If entering Sx, need to disable WAKE# from generating runtime PME
+    }
+    Else
+    { /// If Staying in S0
+      If(LAnd(Arg0, Arg2))  ///- Check if Exiting D0 and arming for wake
+      {
+        Store(1, WKEN)      ///- Set PME
+      } Else {
+        Store(0, WKEN)    ///- Disable runtime PME, either because staying in D0 or disabling wake
+      }
+    }
+  } // End _DSW
+
+  ///
+  /// This method is used to change the GPIO ownership back to ACPI and will be called in PEG OFF Method
+  ///
+  Method(P0EW, 0)
+  {
+    If(WKEN)
+    {
+      If(LNotEqual(SGGP, 0x0))
+      {
+        If(LEqual(SGGP, 0x1))      // GPIO mode
+        {
+          \_SB.SGOV(P0WK, 0x1)
+          \_SB.SHPO(P0WK, 0x0)     // set gpio ownership to ACPI(0=ACPI mode, 1=GPIO mode)
+        }
+      }
+    }
+  } // End P0EW
+
+  Method(_S0W, 0) {
+    Return(4) //D3cold is supported
+  }
+}// end "P.E.G. Root Port D6F0"
+
+///
+/// P.E.G. Root Port D1F0
+///
+Scope(\_SB.PC00.PEG1) {
+  Name(WKEN, 0)
+
+  PowerResource(PG01, 0, 0) {
+    Name(_STA, One)
+    Method(_ON, 0, Serialized) {
+      If(LGreater(OSYS,2009)) {
+        PGON(1)
+        Store(One, _STA)
+      }
+    }
+    Method(_OFF, 0, Serialized) {
+      If(LGreater(OSYS,2009)) {
+        PGOF(1)
+        Store(Zero, _STA)
+      }
+    }
+  } //End of PowerResource(PG01, 0, 0)
+
+  Name(_PR0,Package(){PG01})
+  Name(_PR3,Package(){PG01})
+
+  ///
+  /// This method is used to enable/disable wake from PEG10 (WKEN)
+  ///
+  Method(_DSW, 3)
+  {
+    If(Arg1)
+    {
+      Store(0, WKEN)        /// If entering Sx, need to disable WAKE# from generating runtime PME
+    }
+    Else
+    { /// If Staying in S0
+      If(LAnd(Arg0, Arg2))  ///- Check if Exiting D0 and arming for wake
+      {
+        Store(1, WKEN)      ///- Set PME
+      } Else {
+        Store(0, WKEN)    ///- Disable runtime PME, either because staying in D0 or disabling wake
+      }
+    }
+  } // End _DSW
+
+  ///
+  /// This method is used to change the GPIO ownership back to ACPI and will be called in PEG OFF Method
+  ///
+  Method(P1EW, 0)
+  {
+    If(WKEN)
+    {
+      If(LNotEqual(P1GP, 0x0))
+      {
+        If(LEqual(P1GP, 0x1))      // GPIO mode
+        {
+          \_SB.SGOV(P1WK, 0x1)
+          \_SB.SHPO(P1WK, 0x0)     // set gpio ownership to ACPI(0=ACPI mode, 1=GPIO mode)
+        }
+      }
+    }
+  } // End P1EW
+}// end "P.E.G. Root Port D1F0"
+
+///
+/// P.E.G. Root Port D1F1
+///
+Scope(\_SB.PC00.PEG2) {
+  Name(WKEN, 0)
+
+  PowerResource(PG02, 0, 0) {
+    Name(_STA, One)
+    Method(_ON, 0, Serialized) {
+      If(LGreater(OSYS,2009)) {
+        PGON(2)
+        Store(One, _STA)
+      }
+    }
+    Method(_OFF, 0, Serialized) {
+      If(LGreater(OSYS,2009)) {
+        PGOF(2)
+        Store(Zero, _STA)
+      }
+    }
+  } //End of PowerResource(PG02, 0, 0)
+
+  Name(_PR0,Package(){PG02})
+
+  Name(_PR3,Package(){PG02})
+
+  ///
+  /// This method is used to enable/disable wake from PEG11 (WKEN)
+  ///
+  Method(_DSW, 3)
+  {
+    If(Arg1)
+    {
+      Store(0, WKEN)        /// If entering Sx, need to disable WAKE# from generating runtime PME
+    }
+    Else
+    { /// If Staying in S0
+      If(LAnd(Arg0, Arg2))  ///- Check if Exiting D0 and arming for wake
+      {
+        Store(1, WKEN)      ///- Set PME
+      } Else {
+        Store(0, WKEN)    ///- Disable runtime PME, either because staying in D0 or disabling wake
+      }
+    }
+  } // End _DSW
+
+  ///
+  /// This method is used to change the GPIO ownership back to ACPI and will be called in PEG OFF Method
+  ///
+  Method(P2EW, 0)
+  {
+    If(WKEN)
+    {
+      If(LNotEqual(P2GP, 0x0))
+      {
+        If(LEqual(P2GP, 0x1))      // GPIO mode
+        {
+          \_SB.SGOV(P2WK, 0x1)
+          \_SB.SHPO(P2WK, 0x0)     // set gpio ownership to ACPI(0=ACPI mode, 1=GPIO mode)
+        }
+      }
+    }
+  } // End P2EW
+}// end "P.E.G. Root Port D1F1"
+
+///
+/// P.E.G. Root Port D1F2
+///
+Scope(\_SB.PC00.PEG3) {
+  Name(WKEN, 0)
+
+  PowerResource(PG03, 0, 0) {
+    Name(_STA, One)
+    Method(_ON, 0, Serialized) {
+      If(LGreater(OSYS,2009)) {
+        PGON(3)
+        Store(One, _STA)
+      }
+    }
+    Method(_OFF, 0, Serialized) {
+      If(LGreater(OSYS,2009)) {
+        PGOF(3)
+        Store(Zero, _STA)
+      }
+    }
+  } //End of PowerResource(PG03, 0, 0)
+
+  Name(_PR0,Package(){PG03})
+  Name(_PR3,Package(){PG03})
+
+  ///
+  /// This method is used to enable/disable wake from PEG12 (WKEN)
+  ///
+  Method(_DSW, 3)
+  {
+    If(Arg1)
+    {
+      Store(0, WKEN)        /// If entering Sx, need to disable WAKE# from generating runtime PME
+    }
+    Else
+    { /// If Staying in S0
+      If(LAnd(Arg0, Arg2))  ///- Check if Exiting D0 and arming for wake
+      {
+        Store(1, WKEN)      ///- Set PME
+      } Else {
+        Store(0, WKEN)    ///- Disable runtime PME, either because staying in D0 or disabling wake
+      }
+    }
+  } // End _DSW
+
+  ///
+  /// This method is used to change the GPIO ownership back to ACPI and will be called in PEG OFF Method
+  ///
+  Method(P3EW, 0)
+  {
+    If(WKEN)
+    {
+      If(LNotEqual(P3GP, 0x0))
+      {
+        If(LEqual(P3GP, 0x1))      // GPIO mode
+        {
+          \_SB.SGOV(P3WK, 0x1)
+          \_SB.SHPO(P3WK, 0x0)     // set gpio ownership to ACPI(0=ACPI mode, 1=GPIO mode)
+        }
+      }
+    }
+  } // End P3EW
+}// end "P.E.G. Root Port D1F2"
+
+Scope (\_SB.PC00) {
+
+    Name(IVID, 0xFFFF) //Invalid Vendor ID
+
+    Name(PEBA, 0) //PCIE base address
+
+    Name(PION, 0) //PEG index for ON Method
+    Name(PIOF, 0) //PEG index for OFF Method
+
+    Name(PBUS, 0) //PEG Rootport bus no
+    Name(PDEV, 0) //PEG Rootport device no
+    Name(PFUN, 0) //PEG Rootport function no
+
+    Name(EBUS, 0) //Endpoint bus no
+    Name(EDEV, 0) //Endpoint device no
+    Name(EFN0, 0) //Endpoint function no 0
+    Name(EFN1, 1) //Endpoint function no 1
+
+    Name(LTRS, 0)
+    Name(OBFS, 0)
+
+    Name(DSOF, 0x06) //Device status PCI offset
+    Name(CPOF, 0x34) //Capabilities pointer PCI offset
+    Name(SBOF, 0x19) //PCI-2-PCI Secondary Bus number
+
+    // PEG0 Endpoint variable to save/restore Link Capability, Link control, Subsytem VendorId and Device Id
+    Name (ELC0, 0x00000000)
+    Name (ECP0, 0xffffffff)
+    Name (H0VI, 0x0000)
+    Name (H0DI, 0x0000)
+
+    // PEG1 Endpoint variable to save/restore Link Capability, Link control, Subsytem VendorId and Device Id
+    Name (ELC1, 0x00000000)
+    Name (ECP1, 0xffffffff)
+    Name (H1VI, 0x0000)
+    Name (H1DI, 0x0000)
+
+    // PEG2 Endpoint variable to save/restore Link Capability, Link control, Subsytem VendorId and Device Id
+    Name (ELC2, 0x00000000)
+    Name (ECP2, 0xffffffff)
+    Name (H2VI, 0x0000)
+    Name (H2DI, 0x0000)
+
+    // PEG3 Endpoint variable to save/restore Link Capability, Link control, Subsytem VendorId and Device Id
+    Name (ELC3, 0x00000000)
+    Name (ECP3, 0xffffffff)
+    Name (H3VI, 0x0000)
+    Name (H3DI, 0x0000)
+
+    // PEG_AFELN[15:0]VMTX2_OFFSET variables
+    Name(AFL0, 0)
+    Name(AFL1, 0)
+    Name(AFL2, 0)
+    Name(AFL3, 0)
+    Name(AFL4, 0)
+    Name(AFL5, 0)
+    Name(AFL6, 0)
+    Name(AFL7, 0)
+    Name(AFL8, 0)
+    Name(AFL9, 0)
+    Name(AFLA, 0)
+    Name(AFLB, 0)
+    Name(AFLC, 0)
+    Name(AFLD, 0)
+    Name(AFLE, 0)
+    Name(AFLF, 0)
+
+    //
+    // Define a Memory Region for PEG60 root port that will allow access to its
+    // Register Block.
+    //
+    OperationRegion(OPG0, SystemMemory, Add(XBAS,0x30000), 0x1000)
+    Field(OPG0, AnyAcc,NoLock,Preserve)
+    {
+      Offset(0),
+      P0VI,   16,        //Vendor ID PCI offset
+      P0DI,   16,        //Device ID PCI offset
+      Offset(0x06),
+      DSO0,   16,        //Device status PCI offset
+      Offset(0x34),
+      CPO0,   8,         //Capabilities pointer PCI offset
+      Offset(0x0B0),
+      ,       4,
+      P0LD,   1,         //Link Disable
+      Offset(0x11A),
+      ,       1,
+      P0VC,   1,         //VC0RSTS.VC0NP
+      Offset(0x214),
+      ,       16,
+      P0LS,   4,         //PEGSTS.LKS
+      Offset(0x248),
+      ,       7,
+      Q0L2,   1,         //L23_Rdy Entry Request for RTD3
+      Q0L0,   1,         //L23 to Detect Transition for RTD3
+      Offset(0x504),
+      HST0,  32,
+      Offset(0x508),
+      P0TR,   1,         //TRNEN.TREN
+      Offset(0xC74),
+      P0LT,   4,         //LTSSM_FSM_RESTORE.LTSSM_FSM_PS
+      Offset(0xD0C),
+      LRV0,  32,
+    }
+
+    //
+    // Define a Memory Region for Endpoint on PEG60 root port
+    //
+    OperationRegion (PCS0, SystemMemory, Add(XBAS,ShiftLeft(SBN0,20)), 0xF0)
+    Field(PCS0, DWordAcc, Lock, Preserve)
+    {
+        Offset(0x0),
+        D0VI, 16,
+        Offset(0x2C),
+        S0VI, 16,
+        S0DI, 16,
+    }
+
+    OperationRegion(CAP0, SystemMemory, Add(Add(XBAS,ShiftLeft(SBN0,20)),EECP),0x14)
+    Field(CAP0,DWordAcc, NoLock,Preserve)
+    {
+        Offset(0x0C),                    // Link Capabilities Register
+        LCP0,   32,                      // Link Capabilities Register Data
+        Offset(0x10),
+        LCT0,   16,                      // Link Control register
+    }
+
+    //
+    // Define a Memory Region for PEG10 root port that will allow access to its
+    // Register Block.
+    //
+    OperationRegion(OPG1, SystemMemory, Add(XBAS,0x8000), 0x1000)
+    Field(OPG1, AnyAcc,NoLock,Preserve)
+    {
+      Offset(0),
+      P1VI,   16,        //Vendor ID PCI offset
+      P1DI,   16,        //Device ID PCI offset
+      Offset(0x06),
+      DSO1,   16,        //Device status PCI offset
+      Offset(0x34),
+      CPO1,   8,         //Capabilities pointer PCI offset
+      Offset(0x0B0),
+      ,       4,
+      P1LD,   1,         //Link Disable
+      Offset(0x11A),
+      ,       1,
+      P1VC,   1,         //VC0RSTS.VC0NP
+      Offset(0x214),
+      ,       16,
+      P1LS,   4,         //PEGSTS.LKS
+      Offset(0x248),
+      ,       7,
+      Q1L2,   1,         //L23_Rdy Entry Request for RTD3
+      Q1L0,   1,         //L23 to Detect Transition for RTD3
+      Offset(0x504),
+      HST1,  32,
+      Offset(0x508),
+      P1TR,   1,         //TRNEN.TREN
+      Offset(0x70C),
+      PA0V,  32,         //PEG_AFELN0VMTX2_OFFSET
+      Offset(0x71C),
+      PA1V,  32,         //PEG_AFELN1VMTX2_OFFSET
+      Offset(0x72C),
+      PA2V,  32,         //PEG_AFELN2VMTX2_OFFSET
+      Offset(0x73C),
+      PA3V,  32,         //PEG_AFELN3VMTX2_OFFSET
+      Offset(0x74C),
+      PA4V,  32,         //PEG_AFELN4VMTX2_OFFSET
+      Offset(0x75C),
+      PA5V,  32,         //PEG_AFELN5VMTX2_OFFSET
+      Offset(0x76C),
+      PA6V,  32,         //PEG_AFELN6VMTX2_OFFSET
+      Offset(0x77C),
+      PA7V,  32,         //PEG_AFELN7VMTX2_OFFSET
+      Offset(0x78C),
+      PA8V,  32,         //PEG_AFELN8VMTX2_OFFSET
+      Offset(0x79C),
+      PA9V,  32,         //PEG_AFELN9VMTX2_OFFSET
+      Offset(0x7AC),
+      PAAV,  32,         //PEG_AFELNAVMTX2_OFFSET
+      Offset(0x7BC),
+      PABV,  32,         //PEG_AFELNBVMTX2_OFFSET
+      Offset(0x7CC),
+      PACV,  32,         //PEG_AFELNCVMTX2_OFFSET
+      Offset(0x7DC),
+      PADV,  32,         //PEG_AFELNDVMTX2_OFFSET
+      Offset(0x7EC),
+      PAEV,  32,         //PEG_AFELNEVMTX2_OFFSET
+      Offset(0x7FC),
+      PAFV,  32,         //PEG_AFELNFVMTX2_OFFSET
+      Offset(0x91C),
+      ,       31,
+      BSP1,   1,
+      Offset(0x93C),
+      ,       31,
+      BSP2,   1,
+      Offset(0x95C),
+      ,       31,
+      BSP3,   1,
+      Offset(0x97C),
+      ,       31,
+      BSP4,   1,
+      Offset(0x99C),
+      ,       31,
+      BSP5,   1,
+      Offset(0x9BC),
+      ,       31,
+      BSP6,   1,
+      Offset(0x9DC),
+      ,       31,
+      BSP7,   1,
+      Offset(0x9FC),
+       ,       31,
+      BSP8,   1,
+      Offset(0xC20),
+      ,       4,
+      P1AP,   2,         //AFEOVR.RXSQDETOVR
+      Offset(0xC38),
+      ,       3,
+      P1RM,   1,         //CMNSPARE.PCUNOTL1
+      Offset(0xC3C),
+      ,       31,
+      PRST,   1,
+      Offset(0xC74),
+      P1LT,   4,         //LTSSM_FSM_RESTORE.LTSSM_FSM_PS
+      Offset(0xD0C),
+      LRV1,  32,
+    }
+
+    //
+    // Define a Memory Region for Endpoint on PEG10 root port
+    //
+    OperationRegion (PCS1, SystemMemory, Add(XBAS,ShiftLeft(SBN1,20)), 0xF0)
+    Field(PCS0, DWordAcc, Lock, Preserve)
+    {
+        Offset(0x0),
+        D1VI, 16,
+        Offset(0x2C),
+        S1VI, 16,
+        S1DI, 16,
+    }
+
+    OperationRegion(CAP1, SystemMemory, Add(Add(XBAS,ShiftLeft(SBN1,20)),EEC1),0x14)
+    Field(CAP0,DWordAcc, NoLock,Preserve)
+    {
+        Offset(0x0C),                    // Link Capabilities Register
+        LCP1,   32,                      // Link Capabilities Register Data
+        Offset(0x10),
+        LCT1,   16,                      // Link Control register
+    }
+
+    //
+    // Define a Memory Region for PEG11 root port that will allow access to its
+    // Register Block.
+    //
+    OperationRegion(OPG2, SystemMemory, Add(XBAS,0x9000), 0x1000)
+    Field(OPG2, AnyAcc,NoLock,Preserve)
+    {
+      Offset(0),
+      P2VI,   16,        //Vendor ID PCI offset
+      P2DI,   16,        //Device ID PCI offset
+      Offset(0x06),
+      DSO2,   16,        //Device status PCI offset
+      Offset(0x34),
+      CPO2,   8,         //Capabilities pointer PCI offset
+      Offset(0x0B0),
+      ,       4,
+      P2LD,   1,         //Link Disable
+      Offset(0x11A),
+      ,       1,
+      P2VC,   1,         //VC0RSTS.VC0NP
+      Offset(0x214),
+      ,       16,
+      P2LS,   4,         //PEGSTS.LKS
+      Offset(0x248),
+      ,       7,
+      Q2L2,   1,         //L23_Rdy Entry Request for RTD3
+      Q2L0,   1,         //L23 to Detect Transition for RTD3
+      Offset(0x504),
+      HST2,  32,
+      Offset(0x508),
+      P2TR,   1,         //TRNEN.TREN
+      Offset(0xC20),
+      ,       4,
+      P2AP,   2,         //AFEOVR.RXSQDETOVR
+      Offset(0xC38),
+      ,       3,
+      P2RM,   1,         //CMNSPARE.PCUNOTL1
+      Offset(0xC74),
+      P2LT,   4,         //LTSSM_FSM_RESTORE.LTSSM_FSM_PS
+      Offset(0xD0C),
+      LRV2,  32,
+    }
+
+    //
+    // Define a Memory Region for Endpoint on PEG11 root port
+    //
+    OperationRegion (PCS2, SystemMemory, Add(XBAS,ShiftLeft(SBN2,20)), 0xF0)
+    Field(PCS2, DWordAcc, Lock, Preserve)
+    {
+        Offset(0x0),
+        D2VI, 16,
+        Offset(0x2C),
+        S2VI, 16,
+        S2DI, 16,
+    }
+
+    OperationRegion(CAP2, SystemMemory, Add(Add(XBAS,ShiftLeft(SBN2,20)),EEC2),0x14)
+    Field(CAP2,DWordAcc, NoLock,Preserve)
+    {
+        Offset(0x0C),    // Link Capabilities Register
+        LCP2,   32,      // Link Capabilities Register Data
+        Offset(0x10),
+        LCT2,   16,      // Link Control register
+    }
+
+
+    //
+    // Define a Memory Region for PEG12 root port that will allow access to its
+    // Register Block.
+    //
+    OperationRegion(OPG3, SystemMemory, Add(XBAS,0xA000), 0x1000)
+    Field(OPG3, AnyAcc,NoLock,Preserve)
+    {
+      Offset(0),
+      P3VI,   16,        //Vendor ID PCI offset
+      P3DI,   16,        //Device ID PCI offset
+      Offset(0x06),
+      DSO3,   16,        //Device status PCI offset
+      Offset(0x34),
+      CPO3,   8,         //Capabilities pointer PCI offset
+      Offset(0x0B0),
+      ,       4,
+      P3LD,   1,         //Link Disable
+      Offset(0x11A),
+      ,       1,
+      P3VC,   1,         //VC0RSTS.VC0NP
+      Offset(0x214),
+      ,       16,
+      P3LS,   4,         //PEGSTS.LKS
+      Offset(0x248),
+      ,       7,
+      Q3L2,   1,         //L23_Rdy Entry Request for RTD3
+      Q3L0,   1,         //L23 to Detect Transition for RTD3
+      Offset(0x504),
+      HST3,  32,
+      Offset(0x508),
+      P3TR,   1,         //TRNEN.TREN
+      Offset(0xC20),
+      ,       4,
+      P3AP,   2,         //AFEOVR.RXSQDETOVR
+      Offset(0xC38),
+      ,       3,
+      P3RM,   1,         //CMNSPARE.PCUNOTL1
+      Offset(0xC74),
+      P3LT,   4,         //LTSSM_FSM_RESTORE.LTSSM_FSM_PS
+      Offset(0xD0C),
+      LRV3,  32,
+    }
+
+    //
+    // Define a Memory Region for Endpoint on PEG2 root port
+    //
+    OperationRegion (PCS3, SystemMemory, Add(XBAS,ShiftLeft(SBN3,20)), 0xF0)
+    Field(PCS2, DWordAcc, Lock, Preserve)
+    {
+        Offset(0x0),
+        D3VI, 16,
+        Offset(0x2C),
+        S3VI, 16,
+        S3DI, 16,
+    }
+
+    OperationRegion(CAP3, SystemMemory, Add(Add(XBAS,ShiftLeft(SBN3,20)),EEC3),0x14)
+    Field(CAP3,DWordAcc, NoLock,Preserve)
+    {
+        Offset(0x0C),    // Link Capabilities Register
+        LCP3,   32,      // Link Capabilities Register Data
+        Offset(0x10),
+        LCT3,   16,      // Link Control register
+    }
+
+    //
+    // Name: PGON
+    // Description: Function to put the Pcie Endpoint in ON state
+    // Input: Arg0 -> PEG index
+    // Return: Nothing
+    //
+    Method(PGON,1,Serialized)
+    {
+      Store(Arg0, PION)
+
+      //
+      // Check for the GPIO support on PEG0/1/2/3 Configuration and Return if it is not supported.
+      //
+      If (LEqual(PION, 0))
+      {
+        If (LEqual(SGGP, 0x0))
+        {
+          Return ()
+        }
+      }
+      ElseIf (LEqual(PION, 1))
+      {
+        If (LEqual(P1GP, 0x0))
+        {
+          Return ()
+        }
+      }
+      ElseIf (LEqual(PION, 2))
+      {
+        If (LEqual(P2GP, 0x0))
+        {
+          Return ()
+        }
+      }
+      ElseIf (LEqual(PION, 3))
+      {
+        If (LEqual(P3GP, 0x0))
+        {
+          Return ()
+        }
+      }
+      Store(\XBAS, PEBA)
+      Store(GDEV(PIOF), PDEV)
+      Store(GFUN(PIOF), PFUN)
+
+      /// de-assert CLK_REQ MSK
+      PGSC(Arg0, 1)
+
+      If (LEqual(CCHK(PION, 1), 0))
+      {
+        Return ()
+      }
+
+      //Power on the Endpoint
+      GPPR(PION, 1)
+
+      // Restore PEG Recipe before program L23R2DT
+      //\_SB.PC00.PEG1.RAVR()
+
+      // Enable link for RTD3
+      RTEN()
+
+      // Re-store the DGPU Subsystem VendorID, DeviceID & Link control register data
+      If (LEqual(PION, 0))
+      {
+        Store(H0VI, S0VI)
+        Store(H0DI, S0DI)
+        Or(And(ELC0,0x0043),And(LCT0,0xFFBC),LCT0)
+      }
+      ElseIf (LEqual(PION, 1))
+      {
+        Store(H1VI, S1VI)
+        Store(H1DI, S1DI)
+        Or(And(ELC1,0x0043),And(LCT1,0xFFBC),LCT1)
+      }
+      ElseIf (LEqual(PION, 2))
+      {
+        Store(H2VI, S2VI)
+        Store(H2DI, S2DI)
+        Or(And(ELC2,0x0043),And(LCT2,0xFFBC),LCT2)
+      }
+      ElseIf (LEqual(PION, 3))
+      {
+        Store(H3VI, S3VI)
+        Store(H3DI, S3DI)
+        Or(And(ELC3,0x0043),And(LCT3,0xFFBC),LCT3)
+      }
+      Return ()
+    } // End of Method(PGON,1,Serialized)
+
+    //
+    // Name: PGOF
+    // Description: Function to put the Pcie Endpoint in OFF state
+    // Input: Arg0 -> PEG index
+    // Return: Nothing
+    //
+    Method(PGOF,1,Serialized)
+    {
+
+      Store(Arg0, PIOF)
+      //
+      // Check for the GPIO support on PEG0/1/2 Configuration and Return if it is not supported.
+      //
+      If (LEqual(PIOF, 0))
+      {
+        If (LEqual(SGGP, 0x0))
+        {
+          Return ()
+        }
+      }
+      ElseIf (LEqual(PIOF, 1))
+      {
+        If (LEqual(P1GP, 0x0))
+        {
+          Return ()
+        }
+      }
+      ElseIf (LEqual(PIOF, 2))
+      {
+        If (LEqual(P2GP, 0x0))
+        {
+          Return ()
+        }
+      }
+      ElseIf (LEqual(PIOF, 3))
+      {
+        If (LEqual(P3GP, 0x0))
+        {
+          Return ()
+        }
+      }
+
+      Store(\XBAS, PEBA)
+      Store(GDEV(PIOF), PDEV)
+      Store(GFUN(PIOF), PFUN)
+
+      If (LEqual(CCHK(PIOF, 0), 0))
+      {
+        Return ()
+      }
+
+      // Save Endpoint Link Control register, Subsystem VendorID & Device ID, Link capability Data
+      If (LEqual(Arg0, 0)) //PEG60
+      {
+        Store(LCT0, ELC0)
+        Store(S0VI, H0VI)
+        Store(S0DI, H0DI)
+        Store(LCP0, ECP0)
+      }
+      ElseIf (LEqual(Arg0, 1)) //PEG10
+      {
+        Store(LCT1, ELC1)
+        Store(S1VI, H1VI)
+        Store(S1DI, H1DI)
+        Store(LCP1, ECP1)
+      }
+      ElseIf (LEqual(Arg0, 2)) //PEG11
+      {
+        Store(LCT2, ELC2)
+        Store(S2VI, H2VI)
+        Store(S2DI, H2DI)
+        Store(LCP2, ECP2)
+      }
+      ElseIf (LEqual(Arg0, 3)) //PEG12
+      {
+        Store(LCT3, ELC3)
+        Store(S3VI, H3VI)
+        Store(S3DI, H3DI)
+        Store(LCP3, ECP3)
+      }
+
+      //\_SB.PC00.PEG0.SAVR()
+
+      // Put link in L2
+      RTDS()
+
+      /// assert CLK_REQ MSK
+      ///
+      /// On RTD3 entry, BIOS will instruct the PMC to disable source clocks.
+      /// This is done through sending a PMC IPC command.
+      ///
+      PGSC(Arg0, 0)
+
+      //Power-off the Endpoint
+      GPPR(PIOF, 0)
+      //Method to set Wake GPIO ownership from GPIO to ACPI for Device Initiated RTD3
+      DIWK(PIOF)
+
+      Return ()
+    } // End of Method(PGOF,1,Serialized)
+
+
+    //
+    // Name: GDEV
+    // Description: Function to return the PEG device no for the given PEG index
+    // Input: Arg0 -> PEG index
+    // Return: PEG device no for the given PEG index
+    //
+    Method(GDEV,1)
+    {
+      If(LEqual(Arg0, 0))
+      {
+        Store(0x6, Local0) //Device6-Function0 = 00110.000
+      }
+      ElseIf(LEqual(Arg0, 1))
+      {
+        Store(0x1, Local0) //Device1-Function0 = 00001.000
+      }
+      ElseIf(LEqual(Arg0, 2))
+      {
+        Store(0x1, Local0) //Device1-Function2 = 00001.001
+      }
+      ElseIf(LEqual(Arg0, 3))
+      {
+        Store(0x1, Local0) //Device1-Function3 = 00001.010
+      }
+
+      Return(Local0)
+    } // End of Method(GDEV,1)
+
+    //
+    // Name: GFUN
+    // Description: Function to return the PEG function no for the given PEG index
+    // Input: Arg0 -> PEG index
+    // Return: PEG function no for the given PEG index
+    //
+    Method(GFUN,1)
+    {
+      If(LEqual(Arg0, 0))
+      {
+        Store(0x0, Local0) //Device6-Function0 = 00110.000
+      }
+      ElseIf(LEqual(Arg0, 1))
+      {
+        Store(0x0, Local0) //Device1-Function0 = 00001.000
+      }
+      ElseIf(LEqual(Arg0, 2))
+      {
+        Store(0x1, Local0) //Device1-Function1 = 00001.001
+      }
+      ElseIf(LEqual(Arg0, 2))
+      {
+        Store(0x2, Local0) //Device1-Function2 = 00001.010
+      }
+
+      Return(Local0)
+    } // End of Method(GFUN,1)
+
+    //
+    // Name: CCHK
+    // Description: Function to check whether _ON/_OFF sequence is allowed to execute for the given PEG controller or not
+    // Input: Arg0 -> PEG index
+    //        Arg1 -> 0 means _OFF sequence, 1 means _ON sequence
+    // Return: 0 - Don't execute the flow, 1 - Execute the flow
+    //
+    Method(CCHK,2)
+    {
+
+      //Check for Referenced PEG controller is present or not
+      If(LEqual(Arg0, 0))
+      {
+        Store(P0VI, Local7)
+      }
+      ElseIf(LEqual(Arg0, 1))
+      {
+        Store(P1VI, Local7)
+      }
+      ElseIf(LEqual(Arg0, 2))
+      {
+        Store(P2VI, Local7)
+      }
+      ElseIf(LEqual(Arg0, 3))
+      {
+        Store(P3VI, Local7)
+      }
+
+      If(LEqual(Local7, IVID))
+      {
+        Return(0)
+      }
+
+      If(LNotEqual(Arg0, 1))
+      {
+        //Check for PEG10 controller presence
+        Store(P1VI, Local7)
+        If(LEqual(Local7, IVID))
+        {
+          Return(0)
+        }
+      }
+
+      //If Endpoint is not present[already disabled] before executing PGOF then don't call the PGOF method
+      //If Endpoint is present[already enabled] before executing PGON then don't call the PGON method
+      If(LEqual(Arg1, 0))
+      {
+        //_OFF sequence condition check
+        If(LEqual(Arg0, 0))
+        {
+          If(LEqual(SGPI(SGGP, PWE0, PWG0, PWA0), 0))
+          {
+            Return(0)
+          }
+        }
+        If(LEqual(Arg0, 1))
+        {
+          If(LEqual(SGPI(P1GP, PWE1, PWG1, PWA1), 0))
+          {
+            Return(0)
+          }
+        }
+        If(LEqual(Arg0, 2))
+        {
+          If(LEqual(SGPI(P2GP, PWE2, PWG2, PWA2), 0))
+          {
+            Return(0)
+          }
+        }
+        If(LEqual(Arg0, 3))
+        {
+          If(LEqual(SGPI(P3GP, PWE3, PWG3, PWA3), 0))
+          {
+            Return(0)
+          }
+        }
+      }
+      ElseIf(LEqual(Arg1, 1))
+      {
+        //_ON sequence condition check
+        If(LEqual(Arg0, 0))
+        {
+          If(LEqual(SGPI(SGGP, PWE0, PWG0, PWA0), 1))
+          {
+            Return(0)
+          }
+        }
+        If(LEqual(Arg0, 1))
+        {
+          If(LEqual(SGPI(P1GP, PWE1, PWG1, PWA1), 1))
+          {
+            Return(0)
+          }
+        }
+        If(LEqual(Arg0, 2))
+        {
+          If(LEqual(SGPI(P2GP, PWE2, PWG2, PWA2), 1))
+          {
+            Return(0)
+          }
+        }
+        If(LEqual(Arg0, 3))
+        {
+          If(LEqual(SGPI(P3GP, PWE3, PWG3, PWA3), 1))
+          {
+            Return(0)
+          }
+        }
+      }
+
+      Return(1)
+    }
+
+
+    //
+    // Name: SGPI [PCIe GPIO Read]
+    // Description: Function to Read from PCIe GPIO
+    // Input: Arg0 -> Gpio Support
+    //        Arg1 -> Expander Number
+    //        Arg2 -> Gpio Number
+    //        Arg3 -> Active Information
+    // Return: GPIO value
+    //
+    Method(SGPI, 4, Serialized)
+    {
+      If (LEqual(Arg0, 0x01))
+      {
+        //
+        // PCH based GPIO
+        //
+        If (CondRefOf(\_SB.GGOV))
+        {
+          Store(\_SB.GGOV(Arg2), Local0)
+        }
+      }
+      //
+      // Invert if Active Low
+      //
+      If (LEqual(Arg3,0))
+      {
+        Not(Local0, Local0)
+        And (Local0, 0x01, Local0)
+      }
+
+      Return(Local0)
+    }// End of Method(SGPI)
+
+    // Name: PGSC [PEG port source clock control]
+    // Description: Function to enable/disable PEG port source clocks
+    // Input: Arg0 -> PEG index
+    //        Arg1 -> Enable/Disable Clock (0 = Disable, 1 = Enable)
+    // Return: Nothing
+    //
+
+    Method(PGSC, 2, Serialized)
+    {
+      If(LEqual(Arg0, 0)) { // PEG0
+        Store (P0SC, Local0)
+      } ElseIf(LEqual(Arg0, 1)) { // PEG1
+        Store (P1SC, Local0)
+      } ElseIf(LEqual(Arg0, 2)) { // PEG2
+        Store (P2SC, Local0)
+      } ElseIf(LEqual(Arg0, 3)) {// PEG3
+        Store (P3SC, Local0)
+      } Else {
+        Return()
+      }
+
+      SPCO (Local0, Arg1)
+    }// End of Method(PGSC)
+
+    //
+    // Name: GPPR
+    // Description: Function to do Endpoint ON/OFF using GPIOs
+    //              There are two GPIOs currently used to control Third Party Vendor[TPV] DGPU Endpoint devices:
+    //              (1) DGPU_PWR_EN [used for Power control]
+    //              (2) DGPU_HOLD_RST[used for Reset control]
+    // Input: Arg0 -> PEG index
+    //        Arg1 -> 0 means _OFF sequence, 1 means _ON sequence
+    // Return: Nothing
+    //
+    Method(GPPR,2)
+    {
+
+      If(LEqual(Arg1, 0))
+      {
+        //_OFF sequence GPIO programming
+        If(LEqual(Arg0, 0))
+        {
+          SGPO(SGGP, HRE0, HRG0, HRA0, 1) // Assert PCIe0/dGPU_HOLD_RST# (PERST#)
+          //Sleep(DLHR)                     // As per the PCIe spec, Wait for 'given'ms after Assert the Reset
+          SGPO(SGGP, PWE0, PWG0, PWA0, 0) // Deassert PCIe0/dGPU_PWR_EN#
+        }
+
+        If(LEqual(Arg0, 1))
+        {
+          SGPO(P1GP, HRE1, HRG1, HRA1, 1) // Assert PCIe1_HOLD_RST# (PERST#)
+          //Sleep(DLHR)                     // As per the PCIe spec, Wait for 'given'ms after Assert the Reset
+          SGPO(P1GP, PWE1, PWG1, PWA1, 0) // Deassert PCIe1_PWR_EN#
+        }
+
+        If(LEqual(Arg0, 2))
+        {
+          SGPO(P2GP, HRE2, HRG2, HRA2, 1) // Assert PCIe2_HOLD_RST# (PERST#)
+          //Sleep(DLHR)                     // As per the PCIe spec, Wait for 'given'ms after Assert the Reset
+          SGPO(P2GP, PWE2, PWG2, PWA2, 0) // Deassert PCIe2_PWR_EN#
+        }
+
+        If(LEqual(Arg0, 3))
+        {
+          SGPO(P3GP, HRE3, HRG3, HRA3, 1) // Assert PCIe3_HOLD_RST# (PERST#)
+          //Sleep(DLHR)                     // As per the PCIe spec, Wait for 'given'ms after Assert the Reset
+          SGPO(P3GP, PWE3, PWG3, PWA3, 0) // Deassert PCIe2_PWR_EN#
+        }
+      }
+      ElseIf(LEqual(Arg1, 1))
+      {
+        //_ON sequence GPIO programming
+        If(LEqual(Arg0, 0))
+        {
+          SGPO(SGGP, PWE0, PWG0, PWA0, 1) //Assert dGPU_PWR_EN#
+
+          //Sleep(DLPW) // Wait for 'given'ms for power to get stable
+          SGPO(SGGP, HRE0, HRG0, HRA0, 0) //Deassert dGPU_HOLD_RST# as per the PCIe spec
+
+          //Sleep(DLHR) // Wait for 'given'ms after Deassert
+        }
+
+        If(LEqual(Arg0, 1))
+        {
+          SGPO(P1GP, PWE1, PWG1, PWA1, 1) //Assert dGPU_PWR_EN#
+
+          //Sleep(DLPW) // Wait for 'given'ms for power to get stable
+          SGPO(P1GP, HRE1, HRG1, HRA1, 0) //Deassert dGPU_HOLD_RST# as per the PCIe spec
+
+          //Sleep(DLHR) // Wait for 'given'ms after Deassert
+        }
+
+        If(LEqual(Arg0, 2))
+        {
+          SGPO(P2GP, PWE2, PWG2, PWA2, 1) //Assert dGPU_PWR_EN#
+
+          //Sleep(DLPW) // Wait for 'given'ms for power to get stable
+          SGPO(P2GP, HRE2, HRG2, HRA2, 0) //Deassert dGPU_HOLD_RST# as per the PCIe spec
+
+          //Sleep(DLHR) // Wait for 'given'ms after Deassert
+        }
+
+        If(LEqual(Arg0, 3))
+        {
+          SGPO(P3GP, PWE3, PWG3, PWA3, 1) //Assert dGPU_PWR_EN#
+
+          //Sleep(DLPW) // Wait for 'given'ms for power to get stable
+          SGPO(P3GP, HRE3, HRG3, HRA3, 0) //Deassert dGPU_HOLD_RST# as per the PCIe spec
+
+          //Sleep(DLHR) // Wait for 'given'ms after Deassert
+        }
+      }
+    } // End of Method(GPPR,2)
+
+    //
+    // Name: SGPO [PCIe GPIO Write]
+    // Description: Function to write into PCIe GPIO
+    // Input: Arg0 -> Gpio Support
+    //        Arg1 -> Expander Number
+    //        Arg2 -> Gpio Number
+    //        Arg3 -> Active Information
+    //        Arg4 -> Value to write
+    // Return: Nothing
+    //
+
+    Method(SGPO, 5, Serialized)
+    {
+      //
+      // Invert if Active Low
+      //
+      If (LEqual(Arg3,0))
+      {
+        Not(Arg4, Arg4)
+        And(Arg4, 0x01, Arg4)
+      }
+      If (LEqual(Arg0, 0x01))
+      {
+        //
+        // PCH based GPIO
+        //
+        If (CondRefOf(\_SB.SGOV))
+        {
+          \_SB.SGOV(Arg2, Arg4)
+        }
+      }
+    } // End of Method(SGPO)
+
+    //
+    // Name: DIWK
+    // Description: Function which set the GPIO ownership to ACPI for device initiated RTD3
+    // Input: PEG Index
+    // Return: Nothing
+    //
+    Method(DIWK,1)
+    {
+      If (LEqual(Arg0, 0))
+      {
+        \_SB.PC00.PEG0.P0EW()
+      }
+      ElseIf (LEqual(Arg0, 1))
+      {
+        \_SB.PC00.PEG1.P1EW()
+      }
+      ElseIf (LEqual(Arg0, 2))
+      {
+        \_SB.PC00.PEG2.P2EW()
+      }
+      ElseIf (LEqual(Arg0, 3))
+      {
+        \_SB.PC00.PEG3.P3EW()
+      }
+    }
+  }// End of Scope (\_SB.PC00)
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/PegRtd3.asl b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/PegRtd3.asl
new file mode 100644
index 0000000000..b5d1a4e35e
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/PegRtd3.asl
@@ -0,0 +1,124 @@
+/** @file
+  This file contains the device definitions of the SystemAgent
+  PCIE ACPI Reference Code.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+Scope (\_SB.PC00) {
+
+  OperationRegion(PXCS,PCI_Config,0x00,0x480)
+  Field(PXCS,AnyAcc, NoLock, Preserve)
+  {
+    Offset(0),
+    VDID, 32,
+    Offset(0x50), // LCTL - Link Control Register
+    L0SE, 1,      // 0, L0s Entry Enabled
+    , 3,
+    LDIS, 1,
+    , 3,
+    Offset(0x52), // LSTS - Link Status Register
+    , 13,
+    LASX, 1,      // 0, Link Active Status
+    Offset(0x5A), // SLSTS[7:0] - Slot Status Register
+    ABPX, 1,      // 0, Attention Button Pressed
+    , 2,
+    PDCX, 1,      // 3, Presence Detect Changed
+    , 2,
+    PDSX, 1,      // 6, Presence Detect State
+    , 1,
+    Offset(0x60), // RSTS - Root Status Register
+    , 16,
+    PSPX, 1,      // 16,  PME Status
+    Offset(0xA4),
+    D3HT, 2,      // Power State
+    Offset(0xD8), // 0xD8, MPC - Miscellaneous Port Configuration Register
+    , 30,
+    HPEX, 1,      // 30,  Hot Plug SCI Enable
+    PMEX, 1,      // 31,  Power Management SCI Enable
+    Offset(0xE0), // 0xE0, SPR - Scratch Pad Register
+    , 0,
+    SCB0, 1,      // Sticky Scratch Pad Bit SCB0
+    Offset(0xE2), // 0xE2, RPPGEN - Root Port Power Gating Enable
+    , 2,
+    L23E, 1,       // 2,   L23_Rdy Entry Request (L23ER)
+    L23R, 1,       // 3,   L23_Rdy to Detect Transition (L23R2DT)
+    Offset(0x324), // 0x324 - PCIEDBG
+    , 3,
+    LEDM, 1,       // PCIEDBG.DMIL1EDM
+    Offset(0x328), // 0x328 - PCIESTS1
+    , 24,
+    LTSM, 8,
+  }
+  Field(PXCS,AnyAcc, NoLock, WriteAsZeros)
+  {
+    Offset(0xDC), // 0xDC, SMSCS - SMI/SCI Status Register
+    , 30,
+    HPSX, 1,      // 30,  Hot Plug SCI Status
+    PMSX, 1       // 31,  Power Management SCI Status
+  }
+
+    //
+    // Name: RTEN
+    // Description: Function to Enable the link for RTD3 [RCTL.L22DT]
+    // Input: PEG Index
+    // Return: Nothing
+    //
+    Method(RTEN, 0, Serialized)
+    {
+      If (LNotEqual (SCB0,0x1)) {
+        Return ()
+      }
+
+      /// Set L23_Rdy to Detect Transition  (L23R2DT)
+      Store(1, L23R)
+      Store(0, Local0)
+      /// Wait for transition to Detect
+      While(L23R) {
+        If(Lgreater(Local0, 4))
+        {
+          Break
+        }
+        Sleep(16)
+        Increment(Local0)
+      }
+      Store(0,SCB0)
+
+      /// Once in Detect, wait up to 124 ms for Link Active (typically happens in under 70ms)
+      /// Worst case per PCIe spec from Detect to Link Active is:
+      /// 24ms in Detect (12+12), 72ms in Polling (24+48), 28ms in Config (24+2+2+2+2)
+      Store(0, Local0)
+      While(LEqual(LASX,0)) {
+        If(Lgreater(Local0, 8))
+        {
+          Break
+        }
+        Sleep(16)
+        Increment(Local0)
+      }
+    }
+
+    //
+    // Name: RTDS
+    // Description: Function to Disable link for RTD3 [RCTL.L23ER]
+    // Input: PEG Index
+    // Return: Nothing
+    //
+    Method(RTDS, 0, Serialized)
+    {
+      Store(1, L23E)
+      Sleep(16)
+      Store(0, Local0)
+      While(L23E) {
+        If(Lgreater(Local0, 4))
+        {
+          Break
+        }
+        Sleep(16)
+        Increment(Local0)
+      }
+      Store(1,SCB0)
+    }
+
+} // End of Scope (\_SB.PC00)
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
new file mode 100644
index 0000000000..5228d9d753
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/Sa.asl
@@ -0,0 +1,26 @@
+/** @file
+  This file contains the device definition of the System Agent
+  ACPI reference code.
+  Currently defines the device objects for the
+  System Agent PCI Express* ports (PEG), iGfx and other devices.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+External(\HGMD)
+External(\HGST)
+External(\_SB.PC00, DeviceObj)
+External(\_SB.PC00.GFX0, DeviceObj)
+External(\_SB.PC00.IPU0, DeviceObj)
+External(\_SB.PC00.B0D3, DeviceObj)
+External(\_SB.PC00.PCIC, MethodObj)
+External(\_SB.PC00.PCID, MethodObj)
+///
+/// CPU PCIe Root Port
+///
+include("CpuPcieRp.asl")
+include("PegCommon.asl")
+If(LAnd((LEqual(HGMD,2)), (LEqual(HGST,1)))) {
+  include("PegRtd3.asl")
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl
new file mode 100644
index 0000000000..0494c659e0
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.asl
@@ -0,0 +1,20 @@
+/** @file
+  This file contains the SystemAgent SSDT Table ASL code.
+  It defines a Global NVS table which exchanges datas between OS
+  and BIOS.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+DefinitionBlock (
+  "SaSsdt.aml",
+  "SSDT",
+  0x02,
+  "SaSsdt",
+  "SaSsdt ",
+  0x3000
+  )
+{
+  Include ("Sa.asl")
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf
new file mode 100644
index 0000000000..d0d1494b99
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf
@@ -0,0 +1,22 @@
+## @file
+#  Component description file for the ACPI tables
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION          = 0x00010005
+BASE_NAME            = SaSsdt
+FILE_GUID            = ca89914d-2317-452e-b245-36c6fb77a9c6
+MODULE_TYPE          = USER_DEFINED
+VERSION_STRING       = 1.0
+
+[Sources]
+  SaSsdt.asl
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  TigerlakeSiliconPkg/SiPkg.dec
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.c b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.c
new file mode 100644
index 0000000000..e1569e7f32
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.c
@@ -0,0 +1,254 @@
+/** @file
+  This file provide services for DXE phase policy default initialization
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "DxeSaPolicyLibrary.h"
+#include <Library/DxeGraphicsPolicyLib.h>
+#include <Library/DxeVtdPolicyLib.h>
+#include <Register/SaRegsHostBridge.h>
+
+extern EFI_GUID gMemoryDxeConfigGuid;
+extern EFI_GUID gPcieDxeConfigGuid;
+
+/**
+  This function prints the SA DXE phase policy.
+
+  @param[in] SaPolicy - SA DXE Policy protocol
+**/
+VOID
+SaPrintPolicyProtocol (
+  IN  SA_POLICY_PROTOCOL      *SaPolicy
+  )
+{
+  EFI_STATUS                  Status;
+  PCIE_DXE_CONFIG             *PcieDxeConfig;
+  MEMORY_DXE_CONFIG           *MemoryDxeConfig;
+
+  //
+  // Get requisite IP Config Blocks which needs to be used here
+  //
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gPcieDxeConfigGuid, (VOID *)&PcieDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID *) SaPolicy, &gMemoryDxeConfigGuid, (VOID *)&MemoryDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+
+  DEBUG_CODE_BEGIN ();
+  INTN  i;
+
+  DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (DXE) print BEGIN -----------------\n"));
+  DEBUG ((DEBUG_INFO, "Revision : %x\n", SaPolicy->TableHeader.Header.Revision));
+  ASSERT (SaPolicy->TableHeader.Header.Revision == SA_POLICY_PROTOCOL_REVISION);
+
+  DEBUG ((DEBUG_INFO, "------------------------ SA_MEMORY_CONFIGURATION -----------------\n"));
+
+  DEBUG ((DEBUG_INFO, " SpdAddressTable[%d] :", 4));
+  for (i = 0; i < 4; i++) {
+    DEBUG ((DEBUG_INFO, " %x", MemoryDxeConfig->SpdAddressTable[i]));
+  }
+  DEBUG ((DEBUG_INFO, "\n"));
+
+  DEBUG ((DEBUG_INFO, " ChannelASlotMap : %x\n", MemoryDxeConfig->ChannelASlotMap));
+  DEBUG ((DEBUG_INFO, " ChannelBSlotMap : %x\n", MemoryDxeConfig->ChannelBSlotMap));
+  DEBUG ((DEBUG_INFO, " MrcTimeMeasure  : %x\n", MemoryDxeConfig->MrcTimeMeasure));
+  DEBUG ((DEBUG_INFO, " MrcFastBoot     : %x\n", MemoryDxeConfig->MrcFastBoot));
+
+  DEBUG ((DEBUG_INFO, "------------------------ CPU_PCIE_CONFIGURATION -----------------\n"));
+  DEBUG ((DEBUG_INFO, " PegAspm[%d] :", SA_PEG_MAX_FUN));
+  for (i = 0; i < SA_PEG_MAX_FUN; i++) {
+    DEBUG ((DEBUG_INFO, " %x", PcieDxeConfig->PegAspm[i]));
+  }
+  DEBUG ((DEBUG_INFO, "\n"));
+
+  DEBUG ((DEBUG_INFO, " PegRootPortHPE[%d] :", SA_PEG_MAX_FUN));
+  for (i = 0; i < SA_PEG_MAX_FUN; i++) {
+    DEBUG ((DEBUG_INFO, " %x", PcieDxeConfig->PegRootPortHPE[i]));
+  }
+  DEBUG ((DEBUG_INFO, "\n"));
+
+
+  DEBUG ((DEBUG_INFO, "\n------------------------ SA Policy (DXE) print END -----------------\n"));
+  DEBUG_CODE_END ();
+
+  return;
+}
+
+/**
+  Load DXE Config block default for PCIe
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadPcieDxeDefault (
+  IN VOID    *ConfigBlockPointer
+  )
+{
+  UINT8                  Index;
+  PCIE_DXE_CONFIG        *PcieDxeConfig;
+
+  PcieDxeConfig = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "PcieDxeConfig->Header.GuidHob.Name = %g\n", &PcieDxeConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "PcieDxeConfig->Header.GuidHob.Header.HobLength = 0x%x\n", PcieDxeConfig->Header.GuidHob.Header.HobLength));
+  ///
+  /// Initialize the PCIE Configuration
+  /// PEG ASPM per port configuration. 4 PEG controllers i.e. 0,1,2,3
+  ///
+  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
+    PcieDxeConfig->PegAspm[Index]       = CpuPcieAspmAutoConfig;
+  }
+
+  for (Index = 0; Index < SA_PEG_MAX_FUN; Index++) {
+    PcieDxeConfig->PegPwrOpt[Index].LtrEnable            = 1;
+    PcieDxeConfig->PegPwrOpt[Index].LtrMaxSnoopLatency   = V_SA_LTR_MAX_SNOOP_LATENCY_VALUE;
+    PcieDxeConfig->PegPwrOpt[Index].LtrMaxNoSnoopLatency = V_SA_LTR_MAX_NON_SNOOP_LATENCY_VALUE;
+    PcieDxeConfig->PegPwrOpt[Index].ObffEnable           = 1;
+  }
+}
+
+
+/**
+  Load DXE Config block default
+
+  @param[in] ConfigBlockPointer         Pointer to config block
+**/
+VOID
+LoadMemoryDxeDefault (
+  IN VOID    *ConfigBlockPointer
+  )
+{
+  MEMORY_DXE_CONFIG        *MemoryDxeConfig;
+
+  MemoryDxeConfig = ConfigBlockPointer;
+  DEBUG ((DEBUG_INFO, "MemoryDxeConfig->Header.GuidHob.Name = %g\n", &MemoryDxeConfig->Header.GuidHob.Name));
+  DEBUG ((DEBUG_INFO, "MemoryDxeConfig->Header.GuidHob.Header.HobLength = 0x%x\n", MemoryDxeConfig->Header.GuidHob.Header.HobLength));
+  ///
+  /// Initialize the Memory Configuration
+  ///
+  ///
+  /// DIMM SMBus addresses info
+  /// Refer to the SpdAddressTable[] mapping rule in DxeSaPolicyLibrary.h
+  ///
+  MemoryDxeConfig->SpdAddressTable = AllocateZeroPool (sizeof (UINT8) * 4);
+  ASSERT (MemoryDxeConfig->SpdAddressTable != NULL);
+  if (MemoryDxeConfig->SpdAddressTable != NULL) {
+    MemoryDxeConfig->SpdAddressTable[0] = DIMM_SMB_SPD_P0C0D0;
+    MemoryDxeConfig->SpdAddressTable[1] = DIMM_SMB_SPD_P0C0D1;
+    MemoryDxeConfig->SpdAddressTable[2] = DIMM_SMB_SPD_P0C1D0;
+    MemoryDxeConfig->SpdAddressTable[3] = DIMM_SMB_SPD_P0C1D1;
+  }
+  MemoryDxeConfig->ChannelASlotMap = 0x01;
+  MemoryDxeConfig->ChannelBSlotMap = 0x01;
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED COMPONENT_BLOCK_ENTRY  mSaDxeIpBlocks [] = {
+  {&gPcieDxeConfigGuid,     sizeof (PCIE_DXE_CONFIG),     PCIE_DXE_CONFIG_REVISION,      LoadPcieDxeDefault},
+  {&gMemoryDxeConfigGuid,   sizeof (MEMORY_DXE_CONFIG),   MEMORY_DXE_CONFIG_REVISION,    LoadMemoryDxeDefault}
+};
+
+
+/**
+  CreateSaDxeConfigBlocks generates the config blocks of SA DXE Policy.
+  It allocates and zero out buffer, and fills in the Intel default settings.
+
+  @param[out] SaPolicy               The pointer to get SA  DXE Protocol instance
+
+  @retval EFI_SUCCESS                   The policy default is initialized.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+CreateSaDxeConfigBlocks (
+  IN OUT  SA_POLICY_PROTOCOL      **SaPolicy
+  )
+{
+  UINT16              TotalBlockSize;
+  EFI_STATUS          Status;
+  SA_POLICY_PROTOCOL  *SaInitPolicy;
+  UINT16              RequiredSize;
+
+  DEBUG ((DEBUG_INFO, "SA Create Dxe Config Blocks\n"));
+
+  SaInitPolicy = NULL;
+
+  TotalBlockSize = GetComponentConfigBlockTotalSize (&mSaDxeIpBlocks[0], sizeof (mSaDxeIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+  TotalBlockSize += VtdGetConfigBlockTotalSizeDxe ();
+  TotalBlockSize += GraphicsGetConfigBlockTotalSizeDxe ();
+  DEBUG ((DEBUG_INFO, "TotalBlockSize = 0x%x\n", TotalBlockSize));
+
+  RequiredSize = sizeof (CONFIG_BLOCK_TABLE_HEADER) + TotalBlockSize;
+
+  Status = CreateConfigBlockTable (RequiredSize, (VOID *) &SaInitPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Initialize Policy Revision
+  //
+  SaInitPolicy->TableHeader.Header.Revision = SA_POLICY_PROTOCOL_REVISION;
+  //
+  // Add config blocks.
+  //
+  Status =  AddComponentConfigBlocks ((VOID *) SaInitPolicy, &mSaDxeIpBlocks[0], sizeof (mSaDxeIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+  ASSERT_EFI_ERROR (Status);
+
+  // Vtd
+  Status = VtdAddConfigBlocksDxe((VOID *) SaInitPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  // Gfx
+  Status = GraphicsAddConfigBlocksDxe ((VOID *) SaInitPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Assignment for returning SaInitPolicy config block base address
+  //
+  *SaPolicy = SaInitPolicy;
+  return Status;
+}
+
+
+/**
+  SaInstallPolicyProtocol installs SA Policy.
+  While installed, RC assumes the Policy is ready and finalized. So please update and override
+  any setting before calling this function.
+
+  @param[in] ImageHandle                Image handle of this driver.
+  @param[in] SaPolicy                   The pointer to SA Policy Protocol instance
+
+  @retval EFI_SUCCESS                   The policy is installed.
+  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+SaInstallPolicyProtocol (
+  IN  EFI_HANDLE                  ImageHandle,
+  IN  SA_POLICY_PROTOCOL         *SaPolicy
+  )
+{
+  EFI_STATUS            Status;
+
+  ///
+  /// Print SA DXE Policy
+  ///
+  SaPrintPolicyProtocol (SaPolicy);
+  GraphicsDxePolicyPrint (SaPolicy);
+  VtdPrintPolicyDxe (SaPolicy);
+
+  ///
+  /// Install protocol to to allow access to this Policy.
+  ///
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gSaPolicyProtocolGuid,
+                  SaPolicy,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf
new file mode 100644
index 0000000000..8af3d09b80
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf
@@ -0,0 +1,48 @@
+## @file
+# Component description file for the PeiSaPolicy library.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeSaPolicyLib
+FILE_GUID = B402A3A4-4B82-410E-B79C-5914880A05E7
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = DxeSaPolicyLib
+
+
+[LibraryClasses]
+BaseMemoryLib
+UefiRuntimeServicesTableLib
+UefiBootServicesTableLib
+DebugLib
+PostCodeLib
+ConfigBlockLib
+HobLib
+DxeGraphicsPolicyLib
+DxeVtdPolicyLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+DxeSaPolicyLib.c
+DxeSaPolicyLibrary.h
+
+
+[Guids]
+gPcieDxeConfigGuid
+gMemoryDxeConfigGuid
+
+
+[Protocols]
+gSaPolicyProtocolGuid ## PRODUCES
+
+[Pcd]
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLibrary.h b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLibrary.h
new file mode 100644
index 0000000000..2f64e6eb0d
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLibrary.h
@@ -0,0 +1,33 @@
+/** @file
+  Header file for the DxeSaPolicy library.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _DXE_SA_POLICY_LIBRARY_H_
+#define _DXE_SA_POLICY_LIBRARY_H_
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <CpuPcieConfig.h>
+#include <Protocol/SaPolicy.h>
+
+#define WORD_FIELD_VALID_BIT  BIT15
+#define MAX_PCIE_ASPM_OVERRIDE  500
+#define MAX_PCIE_LTR_OVERRIDE   500
+///
+/// DIMM SMBus addresses
+///
+#define DIMM_SMB_SPD_P0C0D0 0xA0
+#define DIMM_SMB_SPD_P0C0D1 0xA2
+#define DIMM_SMB_SPD_P0C1D0 0xA4
+#define DIMM_SMB_SPD_P0C1D1 0xA6
+#define DIMM_SMB_SPD_P0C0D2 0xA8
+#define DIMM_SMB_SPD_P0C1D2 0xAA
+
+#endif // _DXE_SA_POLICY_LIBRARY_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/PeiDxeSmmSaPlatformLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/PeiDxeSmmSaPlatformLib.inf
new file mode 100644
index 0000000000..0a632fc81a
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/PeiDxeSmmSaPlatformLib.inf
@@ -0,0 +1,32 @@
+## @file
+# Component description file for SA Platform Lib
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmSaPlatformLib
+FILE_GUID = 9DB5ACB4-DB23-43AE-A283-2ABEF365CBE0
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = SaPlatformLib
+
+
+[LibraryClasses]
+BaseLib
+BaseMemoryLib
+DebugLib
+IoLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+SaPlatformLibrary.h
+SaPlatformLibrary.c
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.c b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.c
new file mode 100644
index 0000000000..42902d795c
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.c
@@ -0,0 +1,68 @@
+/** @file
+  SA Platform Lib implementation.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "SaPlatformLibrary.h"
+#include <Library/PciSegmentLib.h>
+#include <IndustryStandard/Pci22.h>
+#include <CpuPcieInfo.h>
+
+
+/**
+  Checks if SKU is Mobile
+
+  @retval FALSE  SKU is not Mobile
+  @retval TRUE   SKU is Mobile
+**/
+BOOLEAN
+EFIAPI
+IsMobileSku (
+  VOID
+  )
+{
+  UINT16           DeviceId;
+
+  DeviceId = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_MC_DEVICE_ID));
+  if (
+      (DeviceId == V_SA_DEVICE_ID_MB_ULT_1) || \
+      (DeviceId == V_SA_DEVICE_ID_MB_ULT_2) || \
+      (DeviceId == V_SA_DEVICE_ID_MB_ULX_1) || \
+      (DeviceId == V_SA_DEVICE_ID_MB_ULX_2) \
+    ) {
+    return TRUE;
+  }
+  return FALSE;
+}
+
+/**
+  Checks if SKU is Desktop
+
+  @retval FALSE  SKU is not Desktop
+  @retval TRUE   SKU is Desktop
+**/
+BOOLEAN
+EFIAPI
+IsDesktopSku (
+  VOID
+  )
+{
+  return FALSE;
+}
+
+/**
+  Checks if SKU is Server
+
+  @retval FALSE  SKU is not Server
+  @retval TRUE   SKU is Server
+**/
+BOOLEAN
+EFIAPI
+IsServerSku (
+  VOID
+  )
+{
+  return FALSE;
+}
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.h b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.h
new file mode 100644
index 0000000000..10513d0ea0
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/Library/PeiDxeSmmSaPlatformLib/SaPlatformLibrary.h
@@ -0,0 +1,21 @@
+/** @file
+  Header file for SA Platform Lib implementation.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SA_PLATFORM_LIBRARY_IMPLEMENTATION_H_
+#define _SA_PLATFORM_LIBRARY_IMPLEMENTATION_H_
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Register/SaRegsHostBridge.h>
+#include <CpuAccess.h>
+#include <Library/SaPlatformLib.h>
+#include <Register/IgdRegs.h>
+
+#endif
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 35/40] TigerlakeSiliconPkg/Fru/TglCpu: Add CpuPcieRp and Vtd library instances
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (32 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 34/40] TigerlakeSiliconPkg/SystemAgent: Add Acpi Tables and " Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 36/40] TigerlakeSiliconPkg/Pch: Add Pch modules Heng Luo
                   ` (4 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * Fru/TglCpu/CpuPcieRp/Library/PeiDxeSmmCpuPcieInfoFruLib
  * Fru/TglCpu/Vtd/LibraryPrivate/DxeVtdInitLib

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/CpuPcieRp/Library/PeiDxeSmmCpuPcieInfoFruLib/CpuPcieInfoFruLib.c            | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/CpuPcieRp/Library/PeiDxeSmmCpuPcieInfoFruLib/PeiDxeSmmCpuPcieInfoFruLib.inf | 36 ++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitFruLib.c                         | 18 ++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitFruLib.inf                       | 39 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 174 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/CpuPcieRp/Library/PeiDxeSmmCpuPcieInfoFruLib/CpuPcieInfoFruLib.c b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/CpuPcieRp/Library/PeiDxeSmmCpuPcieInfoFruLib/CpuPcieInfoFruLib.c
new file mode 100644
index 0000000000..6a9bc89ecf
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/CpuPcieRp/Library/PeiDxeSmmCpuPcieInfoFruLib/CpuPcieInfoFruLib.c
@@ -0,0 +1,81 @@
+/** @file
+  CPU PCIe information library.
+
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Uefi/UefiBaseType.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Register/CpuPcieRegs.h>
+#include <Library/CpuPcieInfoFruLib.h>
+#include <Library/CpuPcieInitCommon.h>
+#include <CpuPcieInfo.h>
+#include <Register/SaRegsHostBridge.h>
+#include <PcieRegs.h>
+
+/**
+  Get Maximum CPU Pcie Root Port Number
+
+  @retval Maximum CPU Pcie Root Port Number
+**/
+UINT8
+GetMaxCpuPciePortNum (
+  VOID
+  )
+{
+  return CPU_PCIE_ULT_ULX_MAX_ROOT_PORT;
+}
+
+/**
+  Get CPU Pcie Root Port Device and Function Number by Root Port physical Number
+
+  @param[in]  RpNumber              Root port physical number. (0-based)
+  @param[out] RpDev                 Return corresponding root port device number.
+  @param[out] RpFun                 Return corresponding root port function number.
+
+  @retval     EFI_SUCCESS           Root port device and function is retrieved
+  @retval     EFI_INVALID_PARAMETER RpNumber is invalid
+**/
+EFI_STATUS
+EFIAPI
+GetCpuPcieRpDevFun (
+  IN  UINTN   RpNumber,
+  OUT UINTN   *RpDev,
+  OUT UINTN   *RpFun
+  )
+{
+  if (RpNumber > GetMaxCpuPciePortNum ()) {
+    DEBUG ((DEBUG_ERROR, "GetCpuPcieRpDevFun invalid RpNumber %x", RpNumber));
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  //  For TGL - U/Y only one CPU PCIE Root port is present
+  //
+  *RpDev = 6;
+  *RpFun = 0;
+  return EFI_SUCCESS;
+}
+/**
+
+  Gets pci segment base address of PCIe root port.
+
+  @param RpIndex    Root Port Index (0 based)
+
+  @return PCIe port base address.
+**/
+UINT64
+CpuPcieBase (
+  IN  UINT32   RpIndex
+  )
+{
+  UINTN   RpDevice;
+  UINTN   RpFunction;
+  GetCpuPcieRpDevFun (RpIndex, &RpDevice, &RpFunction);
+  return PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, (UINT32) RpDevice, (UINT32) RpFunction, 0);
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/CpuPcieRp/Library/PeiDxeSmmCpuPcieInfoFruLib/PeiDxeSmmCpuPcieInfoFruLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/CpuPcieRp/Library/PeiDxeSmmCpuPcieInfoFruLib/PeiDxeSmmCpuPcieInfoFruLib.inf
new file mode 100644
index 0000000000..b6a40b2f7c
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/CpuPcieRp/Library/PeiDxeSmmCpuPcieInfoFruLib/PeiDxeSmmCpuPcieInfoFruLib.inf
@@ -0,0 +1,36 @@
+## @file
+# CPU PCIe information library for TigerLake PCH.
+#
+# 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 = PeiDxeSmmCpuPcieInfoFruLib
+FILE_GUID = 59CA5352-ED46-4449-BF1C-0D0074C4D5B1
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = CpuPcieInfoFruLib
+
+
+[LibraryClasses]
+IoLib
+BaseLib
+DebugLib
+PrintLib
+PcdLib
+ConfigBlockLib
+CpuPcieInitCommonLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Sources]
+CpuPcieInfoFruLib.c
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitFruLib.c b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitFruLib.c
new file mode 100644
index 0000000000..d6e8096da6
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitFruLib.c
@@ -0,0 +1,18 @@
+/** @file
+  DXE FRU Library to initialize Vtd
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Base.h>
+
+/**
+  For device that specified by Device Num and Function Num,
+  mDevEnMap is used to check device presence.
+  0x80 means use Device ID to detemine presence
+  0x8F means force to update
+
+  The structure is used to check if device scope is valid when update DMAR table
+**/
+UINT16  mDevEnMap[][2] = {{0x0200, 0x80}, {0x0500, 0x80}, {0x1400, 0x80}, {0x1401, 0x80}, {0x0700, 0x80}, {0x0701, 0x80}, {0x0702, 0x80}, {0x0703, 0x80}, {0x1302, 0x8F}, {0x1303, 0x8F}};
+UINTN   mDevEnMapSize = sizeof (mDevEnMap) / (sizeof (UINT16) * 2);
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitFruLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitFruLib.inf
new file mode 100644
index 0000000000..e0aa88f68a
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitFruLib.inf
@@ -0,0 +1,39 @@
+## @file
+# Library description file for DXE Phase Vtd Init
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeVtdInitFruLib
+FILE_GUID = 18690D67-08A9-4DCE-B62D-CBE3AF7CFEE7
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_DRIVER
+LIBRARY_CLASS = DxeVtdFruLib
+
+
+[LibraryClasses]
+UefiLib
+UefiRuntimeServicesTableLib
+UefiBootServicesTableLib
+DebugLib
+DxeSaPolicyLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Protocols]
+gSaNvsAreaProtocolGuid                  ## CONSUMES
+
+[Sources]
+DxeVtdInitFruLib.c
+
+[FixedPcd]
+
+[Guids]
+gTcssHobGuid                            ## CONSUMES
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 36/40] TigerlakeSiliconPkg/Pch: Add Pch modules
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (33 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 35/40] TigerlakeSiliconPkg/Fru/TglCpu: Add CpuPcieRp and Vtd " Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 37/40] TigerlakeSiliconPkg/SystemAgent: Add SystemAgent modules Heng Luo
                   ` (3 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * Pch/PchInit/Dxe
  * Pch/PchInit/Smm
  * Pch/PchSmiDispatcher/Smm
  * Pch/SmmControl/RuntimeDxe

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchAcpi.c                      |  494 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchCnviAcpi.c                  |   41 ++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchHdaAcpi.c                   |  201 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchInit.c                      |  314 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchInit.h                      |  122 ++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxe.c                   |  354 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeTgl.inf              |   96 ++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchSata.c                      |   89 ++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIo.c                  |   33 +++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIoDxe.c               |  134 ++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/GbeSxSmm.c                     |  266 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchBiosWriteProtect.c          |  137 +++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchHdaSxSmm.c                  |   33 +++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.c                   |  285 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.h                   |  254 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf                 |  110 +++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchPcieSmm.c                   |  451 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchSpiAsync.c                  |   67 +++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.c              | 1284 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.h              |  226 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatch.c      | 2442 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatcher.inf  |  116 ++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiHelper.h        |   40 +++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiHelperClient.c  |   57 ++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmm.h              | 1043 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmCore.c          |  926 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.c          | 1588 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.h          |  341 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmGpi.c           |  263 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.c       |  332 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.h       |  155 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPeriodicTimer.c |  667 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPowerButton.c   |   81 +++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSw.c            |  381 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSx.c            |  224 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmUsb.c           |  230 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.c      |  778 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.h      |  107 ++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControl.inf       |   54 +++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.c   |  394 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.h   |  130 +++++++++++++++++++++++++++++++++++++++++++++++++
 41 files changed, 15340 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchAcpi.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchAcpi.c
new file mode 100644
index 0000000000..e88afa5ded
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchAcpi.c
@@ -0,0 +1,494 @@
+/** @file
+  This is the driver that initializes the Intel PCH.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include "PchInit.h"
+#include <Protocol/PchPolicy.h>
+#include <GpioDevConfig.h>
+#include <ScsConfig.h>
+#include <Library/PchInfoLib.h>
+#include <Library/GpioLib.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PmcLib.h>
+#include <Library/SerialIoAccessLib.h>
+#include <Library/GbeLib.h>
+#include <PchRstHob.h>
+#include <Library/PchPcieRpLib.h>
+#include <TraceHubConfig.h>
+#include <PchReservedResources.h>
+#include <Library/PciSegmentLib.h>
+#include <Register/PchRegs.h>
+#include <Library/BaseLib.h>
+#include <Register/UsbRegs.h>
+#include <Library/PcdLib.h>
+#include <IndustryStandard/Pci22.h>
+#include <PcieRegs.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchPciBdfLib.h>
+#include <PchHybridStorageHob.h>
+#include <Library/SataLib.h>
+
+//
+// Module variables
+//
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_NVS_AREA_PROTOCOL    mPchNvsAreaProtocol;
+
+/**
+  Retrieve interrupt information about a PCH device from policy
+
+  @param[in] UartNumber                 Uart number
+
+  @retval PCH_DEVICE_INTERRUPT_CONFIG   structure with device's interrupt information
+**/
+PCH_DEVICE_INTERRUPT_CONFIG
+GetUartInterrupt (
+  IN UINT8  UartNumber
+  )
+{
+  PCH_DEVICE_INTERRUPT_CONFIG EmptyRecord;
+  UINT8                       DevNum;
+  UINT8                       FuncNum;
+  UINT8                       Index;
+
+  ZeroMem (&EmptyRecord, sizeof (PCH_DEVICE_INTERRUPT_CONFIG));
+  DevNum  = SerialIoUartDevNumber (UartNumber);
+  FuncNum = SerialIoUartFuncNumber (UartNumber);
+
+  for (Index = 0; Index < mPchConfigHob->Interrupt.NumOfDevIntConfig; Index++) {
+    if ((mPchConfigHob->Interrupt.DevIntConfig[Index].Device == DevNum) &&
+        (mPchConfigHob->Interrupt.DevIntConfig[Index].Function == FuncNum)) {
+      return mPchConfigHob->Interrupt.DevIntConfig[Index];
+    }
+  }
+  return EmptyRecord;
+}
+
+/**
+  Update ASL definitions for SerialIo devices.
+
+**/
+VOID
+UpdateSerialIoAcpiData (
+  VOID
+  )
+{
+  UINT8        Index;
+
+  for (Index = 0; Index < GetPchMaxSerialIoSpiControllersNum (); Index++) {
+    mPchNvsAreaProtocol.Area->SM0[Index] = mPchConfigHob->SerialIo.SpiDeviceConfig[Index].Mode;
+    mPchNvsAreaProtocol.Area->SC0[Index] = GetSerialIoSpiPciCfg (Index);
+  }
+  for (Index = 0; Index < GetPchMaxSerialIoI2cControllersNum (); Index++) {
+    mPchNvsAreaProtocol.Area->IM0[Index] = mPchConfigHob->SerialIo.I2cDeviceConfig[Index].Mode;
+    mPchNvsAreaProtocol.Area->IC0[Index] = GetSerialIoI2cPciCfg (Index);
+  }
+  for (Index = 0; Index < GetPchMaxSerialIoUartControllersNum (); Index++) {
+    mPchNvsAreaProtocol.Area->UM0[Index] = mPchConfigHob->SerialIo.UartDeviceConfig[Index].Mode;
+    mPchNvsAreaProtocol.Area->UC0[Index] = GetSerialIoUartPciCfg (Index);
+    mPchNvsAreaProtocol.Area->UD0[Index] = mPchConfigHob->SerialIo.UartDeviceConfig[Index].DmaEnable;
+    mPchNvsAreaProtocol.Area->UP0[Index] = mPchConfigHob->SerialIo.UartDeviceConfig[Index].PowerGating;
+    mPchNvsAreaProtocol.Area->UI0[Index] = (GetUartInterrupt (Index)).Irq;
+  }
+}
+
+#if FixedPcdGet8(PcdEmbeddedEnable) == 0x1
+/**
+  Update NVS Area for Timed GPIO devices.
+**/
+VOID
+UpdateTimedGpioSetup (
+  VOID
+  )
+{
+  mPchNvsAreaProtocol.Area->EnableTimedGpio0 = (UINT8)mPchConfigHob->Pm.EnableTimedGpio0;
+  mPchNvsAreaProtocol.Area->EnableTimedGpio1 = (UINT8)mPchConfigHob->Pm.EnableTimedGpio1;
+}
+#endif
+
+/**
+  Update NVS Area after RST PCIe Storage Remapping and before Boot
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_NOT_FOUND           Couldn't fetch RstHob
+**/
+EFI_STATUS
+PchUpdateNvsAreaAfterRemapping (
+  VOID
+  )
+{
+  UINTN                 Index;
+  VOID                  *Hob;
+  PCH_RST_HOB           *RstHob;
+
+  Hob = GetFirstGuidHob (&gPchRstHobGuid);
+  if (Hob == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  RstHob = (PCH_RST_HOB *) GET_GUID_HOB_DATA (Hob);
+
+  for (Index = 0; Index < PCH_MAX_RST_PCIE_STORAGE_CR; Index++) {
+    mPchNvsAreaProtocol.Area->RstPcieStorageInterfaceType[Index]        = RstHob->RstCrConfiguration[Index].DeviceInterface;
+    mPchNvsAreaProtocol.Area->RstPcieStoragePmCapPtr[Index]             = RstHob->SavedRemapedDeviceConfigSpace[Index].PmCapPtr;
+    mPchNvsAreaProtocol.Area->RstPcieStoragePcieCapPtr[Index]           = RstHob->SavedRemapedDeviceConfigSpace[Index].PcieCapPtr;
+    mPchNvsAreaProtocol.Area->RstPcieStorageL1ssCapPtr[Index]           = RstHob->SavedRemapedDeviceConfigSpace[Index].L1ssCapPtr;
+    mPchNvsAreaProtocol.Area->RstPcieStorageEpL1ssControl2[Index]       = RstHob->SavedRemapedDeviceConfigSpace[Index].EndpointL1ssControl2;
+    mPchNvsAreaProtocol.Area->RstPcieStorageEpL1ssControl1[Index]       = RstHob->SavedRemapedDeviceConfigSpace[Index].EndpointL1ssControl1;
+    mPchNvsAreaProtocol.Area->RstPcieStorageLtrCapPtr[Index]            = RstHob->SavedRemapedDeviceConfigSpace[Index].LtrCapPtr;
+    mPchNvsAreaProtocol.Area->RstPcieStorageEpLtrData[Index]            = RstHob->SavedRemapedDeviceConfigSpace[Index].EndpointLtrData;
+    mPchNvsAreaProtocol.Area->RstPcieStorageEpLctlData16[Index]         = RstHob->SavedRemapedDeviceConfigSpace[Index].EndpointLctlData16;
+    mPchNvsAreaProtocol.Area->RstPcieStorageEpDctlData16[Index]         = RstHob->SavedRemapedDeviceConfigSpace[Index].EndpointDctlData16;
+    mPchNvsAreaProtocol.Area->RstPcieStorageEpDctl2Data16[Index]        = RstHob->SavedRemapedDeviceConfigSpace[Index].EndpointDctl2Data16;
+    mPchNvsAreaProtocol.Area->RstPcieStorageRpDctl2Data16[Index]        = RstHob->SavedRemapedDeviceConfigSpace[Index].RootPortDctl2Data16;
+    mPchNvsAreaProtocol.Area->RstPcieStorageUniqueTableBar[Index]       = RstHob->RstCrConfiguration[Index].EndPointUniqueMsixTableBar;
+    mPchNvsAreaProtocol.Area->RstPcieStorageUniqueTableBarValue[Index]  = RstHob->RstCrConfiguration[Index].EndPointUniqueMsixTableBarValue;
+    mPchNvsAreaProtocol.Area->RstPcieStorageUniquePbaBar[Index]         = RstHob->RstCrConfiguration[Index].EndPointUniqueMsixPbaBar;
+    mPchNvsAreaProtocol.Area->RstPcieStorageUniquePbaBarValue[Index]    = RstHob->RstCrConfiguration[Index].EndPointUniqueMsixPbaBarValue;
+    mPchNvsAreaProtocol.Area->RstPcieStorageRootPortNum[Index]          = RstHob->RstCrConfiguration[Index].RootPortNum;
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  Update the Hybrid storage location NVS Area if Hybrid Storage device is present
+**/
+EFI_STATUS
+UpdateHybridStorageLocation (
+  VOID
+  )
+{
+  VOID                               *Hob;
+  PCH_HYBRIDSTORAGE_HOB              *HybridStorageHob;
+
+  Hob = GetFirstGuidHob (&gHybridStorageHobGuid);
+  if (Hob == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  HybridStorageHob = (PCH_HYBRIDSTORAGE_HOB *) GET_GUID_HOB_DATA (Hob);
+  mPchNvsAreaProtocol.Area->HybridStorageLocation = HybridStorageHob->HybridStorageLocation;
+  return EFI_SUCCESS;
+}
+
+/**
+  PCH ACPI initialization before Boot Sript Table is closed
+  It update ACPI table and ACPI NVS area.
+
+  @param[in] Event                A pointer to the Event that triggered the callback.
+  @param[in] Context              A pointer to private data registered with the callback function.
+**/
+VOID
+EFIAPI
+PchAcpiOnEndOfDxe (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  )
+{
+  DEBUG ((DEBUG_INFO, "PchAcpiOnEndOfDxe() Start\n"));
+
+  ///
+  /// Closed the event to avoid call twice when launch shell
+  ///
+  gBS->CloseEvent (Event);
+
+  //
+  // Init HDA Audio ACPI tables
+  //
+  PchHdAudioAcpiInit ();
+  //
+  // Update ASL definitions for SerialIo devices.
+  //
+  UpdateSerialIoAcpiData ();
+  UpdateCnviAcpiData ();
+#if FixedPcdGet8(PcdEmbeddedEnable) == 0x1
+  UpdateTimedGpioSetup();
+#endif
+
+  //
+  // Update Pch Nvs Area
+  //
+  PchUpdateNvsArea ();
+
+  DEBUG ((DEBUG_INFO, "PchAcpiOnEndOfDxe() End\n"));
+
+  return;
+}
+
+/**
+  Initialize Pch acpi
+  @param[in] ImageHandle          Handle for the image of this driver
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+PchAcpiInit (
+  IN EFI_HANDLE         ImageHandle
+  )
+{
+  EFI_STATUS  Status;
+  EFI_EVENT   EndOfDxeEvent;
+
+  DEBUG ((DEBUG_INFO, "Install PCH NVS protocol\n"));
+
+  Status = (gBS->AllocatePool) (EfiACPIMemoryNVS, sizeof (PCH_NVS_AREA), (VOID **) &mPchNvsAreaProtocol.Area);
+  ASSERT_EFI_ERROR (Status);
+
+  ZeroMem ((VOID *) mPchNvsAreaProtocol.Area, sizeof (PCH_NVS_AREA));
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gPchNvsAreaProtocolGuid,
+                  &mPchNvsAreaProtocol,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Update the NVS Area after RST PCIe Storage Remapping
+  ///
+  PchUpdateNvsAreaAfterRemapping ();
+
+  UpdateHybridStorageLocation ();
+  //
+  // Register an end of DXE event for PCH ACPI to do tasks before invoking any UEFI drivers,
+  // applications, or connecting consoles,...
+  //
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  PchAcpiOnEndOfDxe,
+                  NULL,
+                  &gEfiEndOfDxeEventGroupGuid,
+                  &EndOfDxeEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+
+/**
+  Update NVS area for PCIe root ports.
+**/
+STATIC
+VOID
+PcieRpUpdateNvsArea (
+  VOID
+  )
+{
+  UINT32  Index;
+
+  for (Index = 0; Index < PCH_MAX_PCIE_CLOCKS; Index++) {
+    mPchNvsAreaProtocol.Area->ClockToRootPortMap[Index] = mPchConfigHob->PcieRp.PcieClock[Index].Usage;
+  }
+}
+
+/**
+  Update ASL object before Boot
+
+  @retval EFI_STATUS
+  @retval EFI_NOT_READY         The Acpi protocols are not ready.
+**/
+EFI_STATUS
+PchUpdateNvsArea (
+  VOID
+  )
+{
+  EFI_STATUS            Status;
+  UINTN                 Index;
+  UINT32                HpetBaseAdress;
+  GPIO_GROUP            GroupToGpeDwX[3];
+  UINT32                GroupDw[3];
+  UINTN                 RpDev;
+  UINTN                 RpFun;
+  UINT32                Data32;
+  PCH_POLICY_PROTOCOL   *PchPolicy;
+  GPIO_DXE_CONFIG       *GpioDxeConfig;
+  UINT64                XdciPciBase;
+  UINT64                XdciBar;
+  UINT16                PciMemConfig;
+  UINT16                TcoBase;
+  UINT8                 ClearXdciBar = FALSE;
+
+  ///
+  /// Get PCH Policy Protocol
+  ///
+  Status = gBS->LocateProtocol (&gPchPolicyProtocolGuid, NULL, (VOID **)&PchPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Get GPIO DXE Config Block
+  ///
+  Status = GetConfigBlock ((VOID *)PchPolicy, &gGpioDxeConfigGuid, (VOID *)&GpioDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Update ASL PCIE port address according to root port device and function
+  //
+  for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
+    RpDev = PchPcieRpDevNumber (Index);
+    RpFun = PchPcieRpFuncNumber (Index);
+    Data32 = ((UINT8) RpDev << 16) | (UINT8) RpFun;
+    mPchNvsAreaProtocol.Area->RpAddress[Index] = Data32;
+
+    //
+    // Update Maximum Snoop Latency and Maximum No-Snoop Latency values for PCIE
+    //
+    mPchNvsAreaProtocol.Area->PcieLtrMaxSnoopLatency[Index]   = mPchConfigHob->PcieRp.RootPort[Index].PcieRpCommonConfig.PcieRpLtrConfig.LtrMaxSnoopLatency;
+    mPchNvsAreaProtocol.Area->PcieLtrMaxNoSnoopLatency[Index] = mPchConfigHob->PcieRp.RootPort[Index].PcieRpCommonConfig.PcieRpLtrConfig.LtrMaxNoSnoopLatency;
+  }
+
+  //
+  // Update PCHS.
+  //
+  mPchNvsAreaProtocol.Area->PchSeries     = PchSeries ();
+  //
+  // Update PCHG.
+  //
+  mPchNvsAreaProtocol.Area->PchGeneration = (UINT16) PchGeneration ();
+  //
+  // Update PSTP.
+  //
+  mPchNvsAreaProtocol.Area->PchStepping = (UINT16) PchStepping ();
+  //
+  // Update HPET base address.
+  //
+  PchHpetBaseGet (&HpetBaseAdress);
+  mPchNvsAreaProtocol.Area->HPTE          = TRUE;  // @todo remove the NVS, since it's always enabled.
+  mPchNvsAreaProtocol.Area->HPTB          = HpetBaseAdress;
+  //
+  // Update SBREG_BAR.
+  //
+  mPchNvsAreaProtocol.Area->SBRG          = PCH_PCR_BASE_ADDRESS;
+
+  //
+  // Update base address
+  //
+  mPchNvsAreaProtocol.Area->PMBS = PmcGetAcpiBase ();
+  mPchNvsAreaProtocol.Area->PWRM = PmcGetPwrmBase ();
+  PchTcoBaseGet (&TcoBase);
+  mPchNvsAreaProtocol.Area->TcoBase = TcoBase;
+
+  //
+  // Update PCH PID info
+  //
+  mPchNvsAreaProtocol.Area->IclkPid = PchPcrGetPid (PchIpIclk);
+
+  //
+  // Update GPIO device ACPI variables
+  //
+  mPchNvsAreaProtocol.Area->SGIR = mPchConfigHob->Interrupt.GpioIrqRoute;
+  mPchNvsAreaProtocol.Area->GPHD = (UINT8)GpioDxeConfig->HideGpioAcpiDevice;
+
+  //
+  // Update GPP_X to GPE_DWX mapping.
+  //
+  GpioGetGroupDwToGpeDwX (
+    &GroupToGpeDwX[0], &GroupDw[0],
+    &GroupToGpeDwX[1], &GroupDw[1],
+    &GroupToGpeDwX[2], &GroupDw[2]
+    );
+
+  //
+  // GEI0/1/2 and GED0/1/2 are objects for informing how GPIO groups are mapped to GPE0.
+  // If Group is mapped to 1-Tier GPE information is also stored on what Group DW
+  // is mapped to GPE_DWx. Because GPE_DWx register is 32 bits large if groups have more than
+  // 32 pads only part of it can be mapped.
+  //
+  //  GEIx - GroupIndex mapped to GPE0_DWx
+  //  GEDx - DoubleWorld part of Group: 0 - pins 31-0, 1 - pins 63-32, ...
+  //
+  mPchNvsAreaProtocol.Area->GEI0 = (UINT8) GpioGetGroupIndexFromGroup (GroupToGpeDwX[0]);
+  mPchNvsAreaProtocol.Area->GEI1 = (UINT8) GpioGetGroupIndexFromGroup (GroupToGpeDwX[1]);
+  mPchNvsAreaProtocol.Area->GEI2 = (UINT8) GpioGetGroupIndexFromGroup (GroupToGpeDwX[2]);
+  mPchNvsAreaProtocol.Area->GED0 = (UINT8) GroupDw[0];
+  mPchNvsAreaProtocol.Area->GED1 = (UINT8) GroupDw[1];
+  mPchNvsAreaProtocol.Area->GED2 = (UINT8) GroupDw[2];
+
+  //
+  // SCS Configuration
+  //
+
+  PcieRpUpdateNvsArea ();
+
+  //
+  // SATA configuration.
+  //
+  mPchNvsAreaProtocol.Area->SataPortPresence = GetSataPortPresentStatus (0);
+  DEBUG ((DEBUG_INFO, "SataPortPresence: 0x%x\n", mPchNvsAreaProtocol.Area->SataPortPresence));
+
+  //
+  // CPU SKU
+  //
+  mPchNvsAreaProtocol.Area->CpuSku = 0;
+  mPchNvsAreaProtocol.Area->PsOnEnable            = (UINT8)mPchConfigHob->Pm.PsOnEnable;
+
+  for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
+    mPchNvsAreaProtocol.Area->LtrEnable[Index]  = (UINT8)mPchConfigHob->PcieRp.RootPort[Index].PcieRpCommonConfig.LtrEnable;
+  }
+
+  mPchNvsAreaProtocol.Area->GBES = IsGbePresent ();
+
+  //
+  // Update PCH Trace Hub Mode
+  //
+  mPchNvsAreaProtocol.Area->PchTraceHubMode     = (UINT8) mPchConfigHob->PchTraceHub.PchTraceHubMode;
+
+  //
+  // Saving GCTL value into PCH NVS area
+  //
+
+  XdciPciBase = PchXdciPciCfgBase ();
+
+  //
+  // Determine Base address for Base address register (Offset 0x10)
+  //
+  if (PciSegmentRead32 (XdciPciBase) != 0xFFFFFFFF) {
+
+    XdciBar = PciSegmentRead32 (XdciPciBase + PCI_BASE_ADDRESSREG_OFFSET) & 0xFFFFFFF0;
+
+    if ((PciSegmentRead32 (XdciPciBase + PCI_BASE_ADDRESSREG_OFFSET) & B_PCI_BAR_MEMORY_TYPE_MASK) == B_PCI_BAR_MEMORY_TYPE_64) {
+      XdciBar += (UINT64)PciSegmentRead32 (XdciPciBase + (PCI_BASE_ADDRESSREG_OFFSET + 4)) << 32;
+    }
+
+    if (XdciBar == 0x0) {
+      ClearXdciBar = TRUE;
+      PciSegmentWrite32 ((XdciPciBase + PCI_BASE_ADDRESSREG_OFFSET), PcdGet32 (PcdSiliconInitTempMemBaseAddr));
+      XdciBar = PciSegmentRead32 (XdciPciBase + PCI_BASE_ADDRESSREG_OFFSET) & 0xFFFFFFF0;
+
+      if ((PciSegmentRead32 (XdciPciBase + PCI_BASE_ADDRESSREG_OFFSET) & B_PCI_BAR_MEMORY_TYPE_MASK) == B_PCI_BAR_MEMORY_TYPE_64) {
+        XdciBar += (UINT64)PciSegmentRead32 (XdciPciBase + (PCI_BASE_ADDRESSREG_OFFSET + 4)) << 32;
+      }
+    }
+
+    //
+    // Enable Pci Memconfig to read the correct value for GCTL register
+    //
+    PciMemConfig = PciSegmentRead16 (XdciPciBase + PCI_COMMAND_OFFSET);
+    PciSegmentWrite16 (XdciPciBase + PCI_COMMAND_OFFSET, PciMemConfig | (EFI_PCI_COMMAND_BUS_MASTER | EFI_PCI_COMMAND_MEMORY_SPACE));
+
+    mPchNvsAreaProtocol.Area->PchxDCIPwrDnScale = MmioRead32(XdciBar + R_XDCI_MEM_GCTL);
+    DEBUG ((DEBUG_INFO, "PchxDCIPwrDnScale  0x%x\n", (UINT64)mPchNvsAreaProtocol.Area->PchxDCIPwrDnScale));
+    //
+    // Disable Pci Memconfig & clear Base address
+    //
+    PciSegmentWrite16(XdciPciBase + PCI_COMMAND_OFFSET, PciMemConfig);
+
+    if (ClearXdciBar == TRUE) {
+      PciSegmentWrite32 ((XdciPciBase + PCI_BASE_ADDRESSREG_OFFSET), 0x0);
+      PciSegmentWrite32 ((XdciPciBase + (PCI_BASE_ADDRESSREG_OFFSET + 4)), 0x0);
+    }
+  }
+
+  return Status;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchCnviAcpi.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchCnviAcpi.c
new file mode 100644
index 0000000000..5c8e1ce5b4
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchCnviAcpi.c
@@ -0,0 +1,41 @@
+/** @file
+  Initializes PCH CNVi device ACPI data.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <CnviConfigHob.h>
+#include "PchInit.h"
+#include <Register/PchPcrRegs.h>
+
+/**
+  Update ASL definitions for CNVi device.
+
+  @retval EFI_SUCCESS         The function completed successfully
+**/
+EFI_STATUS
+UpdateCnviAcpiData (
+  VOID
+  )
+{
+  EFI_PEI_HOB_POINTERS HobPtr;
+  CNVI_CONFIG_HOB      *CnviConfigHob;
+
+  DEBUG ((DEBUG_INFO, "UpdateCnviAcpiData() Start\n"));
+
+  // Get CNVi Config HOB.
+  HobPtr.Guid = GetFirstGuidHob (&gCnviConfigHobGuid);
+  if (HobPtr.Guid != NULL) {
+    CnviConfigHob = (CNVI_CONFIG_HOB *) GET_GUID_HOB_DATA (HobPtr.Guid);
+    mPchNvsAreaProtocol.Area->CnviMode           = (UINT8)CnviConfigHob->Mode;
+    mPchNvsAreaProtocol.Area->CnviBtCore         = (UINT8)CnviConfigHob->BtCore;
+    mPchNvsAreaProtocol.Area->CnviBtAudioOffload = (UINT8)CnviConfigHob->BtAudioOffload;
+  }
+  mPchNvsAreaProtocol.Area->CnviPortId = PID_CNVI;
+  DEBUG ((DEBUG_INFO, "UpdateCnviAcpiData() End\n"));
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchHdaAcpi.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchHdaAcpi.c
new file mode 100644
index 0000000000..dbdb028483
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchHdaAcpi.c
@@ -0,0 +1,201 @@
+
+/** @file
+  Initializes the PCH HD Audio ACPI Tables.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Protocol/AcpiTable.h>
+#include <DxeHdaNhlt.h>
+#include <Library/DxeHdaNhltLib.h>
+#include "PchInit.h"
+#include <HdAudioConfig.h>
+#include <PchConfigHob.h>
+#include <Library/PcdLib.h>
+#include <Protocol/PchPolicy.h>
+#include <HdAudioConfig.h>
+#include <IndustryStandard/Pci30.h>
+#include <Register/PchRegs.h>
+#include <Library/PchPciBdfLib.h>
+#include <Library/PchInfoLib.h>
+
+#define XTAL_FREQ_38P4MHZ    1
+
+/**
+  Retrieves address of NHLT table from XSDT/RSDT.
+
+  @retval NHLT_ACPI_TABLE*  Pointer to NHLT table if found
+  @retval NULL              NHLT could not be found
+**/
+NHLT_ACPI_TABLE *
+LocateNhltAcpiTable (
+  VOID
+  )
+{
+  EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER  *Rsdp;
+  EFI_ACPI_DESCRIPTION_HEADER                   *Xsdt;
+  NHLT_ACPI_TABLE                               *Nhlt;
+  UINTN                                         Index;
+  UINT64                                        Data64;
+  EFI_STATUS                                    Status;
+  Rsdp  = NULL;
+  Xsdt  = NULL;
+  Nhlt  = NULL;
+
+  ///
+  /// Find the AcpiSupport protocol returns RSDP (or RSD PTR) address.
+  ///
+  DEBUG ((DEBUG_INFO, "LocateNhltAcpiTable() Start\n"));
+
+  Status = EfiGetSystemConfigurationTable (&gEfiAcpiTableGuid, (VOID *) &Rsdp);
+  if (EFI_ERROR (Status) || (Rsdp == NULL)) {
+    DEBUG ((DEBUG_ERROR, "EFI_ERROR or Rsdp == NULL\n"));
+    return NULL;
+  }
+
+  Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->XsdtAddress;
+  if (Xsdt == NULL || Xsdt->Signature != EFI_ACPI_5_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
+    // If XSDT has not been found, check RSDT
+    Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->RsdtAddress;
+    if (Xsdt == NULL || Xsdt->Signature != EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
+      DEBUG ((DEBUG_ERROR, "XSDT/RSDT == NULL or wrong signature\n"));
+      return NULL;
+    }
+  }
+
+  for (Index = sizeof (EFI_ACPI_DESCRIPTION_HEADER); Index < Xsdt->Length; Index = Index + sizeof (UINT64)) {
+    Data64  = *(UINT64 *) ((UINT8 *) Xsdt + Index);
+    Nhlt    = (NHLT_ACPI_TABLE *) (UINTN) Data64;
+    if (Nhlt != NULL && Nhlt->Header.Signature == NHLT_ACPI_TABLE_SIGNATURE) {
+      break;
+    }
+    Nhlt = NULL;
+  }
+
+  if (Nhlt == NULL || Nhlt->Header.Signature != NHLT_ACPI_TABLE_SIGNATURE) {
+    DEBUG ((DEBUG_ERROR, "Nhlt == NULL or wrong signature\n"));
+    return NULL;
+  }
+
+  DEBUG ((DEBUG_INFO, "Found NhltTable, Address = 0x%016x\n", Nhlt));
+
+  return Nhlt;
+}
+
+/**
+  Sets NVS ACPI variables for HDAS._DSM and SNDW._DSD accordingly to policy.
+
+  @param[in]                NhltAcpiTableAddress
+  @param[in]                NhltAcpiTableLength
+  @param[in]                *HdAudioConfigHob
+  @param[in]                *HdAudioDxeConfig
+**/
+VOID
+UpdateHdaAcpiData (
+  IN       UINT64                 NhltAcpiTableAddress,
+  IN       UINT32                 NhltAcpiTableLength,
+  IN CONST HDAUDIO_HOB            *HdAudioConfigHob,
+  IN CONST HDAUDIO_DXE_CONFIG     *HdAudioDxeConfig
+  )
+{
+  DEBUG ((DEBUG_INFO, "UpdateHdaAcpiData():\n NHLT Address = 0x%016x, Length = 0x%08x\n", NhltAcpiTableAddress, NhltAcpiTableLength));
+  DEBUG ((DEBUG_INFO, " FeatureMask = 0x%08x\n", HdAudioDxeConfig->DspFeatureMask));
+
+  mPchNvsAreaProtocol.Area->XTAL = XTAL_FREQ_38P4MHZ;
+  mPchNvsAreaProtocol.Area->NHLA = NhltAcpiTableAddress;
+  mPchNvsAreaProtocol.Area->NHLL = NhltAcpiTableLength;
+  mPchNvsAreaProtocol.Area->ADFM = HdAudioDxeConfig->DspFeatureMask;
+
+  if (HdAudioConfigHob->DspEnable || HdAudioConfigHob->DspUaaCompliance == FALSE) {
+    mPchNvsAreaProtocol.Area->SWQ0 = HdAudioConfigHob->AudioLinkSndw1 ? 0 : BIT1;
+    mPchNvsAreaProtocol.Area->SWQ1 = HdAudioConfigHob->AudioLinkSndw2 ? 0 : BIT1;
+    mPchNvsAreaProtocol.Area->SWQ2 = HdAudioConfigHob->AudioLinkSndw3 ? 0 : BIT1;
+    mPchNvsAreaProtocol.Area->SWQ3 = HdAudioConfigHob->AudioLinkSndw4 ? 0 : BIT1;
+  } else {
+    mPchNvsAreaProtocol.Area->SWQ0 = BIT1;
+    mPchNvsAreaProtocol.Area->SWQ1 = BIT1;
+    mPchNvsAreaProtocol.Area->SWQ2 = BIT1;
+    mPchNvsAreaProtocol.Area->SWQ3 = BIT1;
+  }
+
+  mPchNvsAreaProtocol.Area->SWMC = GetPchHdaMaxSndwLinkNum ();
+
+  mPchNvsAreaProtocol.Area->ACS0 = (UINT8)HdAudioDxeConfig->SndwConfig[0].AutonomousClockStop;
+  mPchNvsAreaProtocol.Area->ACS1 = (UINT8)HdAudioDxeConfig->SndwConfig[1].AutonomousClockStop;
+  mPchNvsAreaProtocol.Area->ACS2 = (UINT8)HdAudioDxeConfig->SndwConfig[2].AutonomousClockStop;
+  mPchNvsAreaProtocol.Area->ACS3 = (UINT8)HdAudioDxeConfig->SndwConfig[3].AutonomousClockStop;
+
+  mPchNvsAreaProtocol.Area->DAI0 = (UINT8)HdAudioDxeConfig->SndwConfig[0].DataOnActiveIntervalSelect;
+  mPchNvsAreaProtocol.Area->DAI1 = (UINT8)HdAudioDxeConfig->SndwConfig[1].DataOnActiveIntervalSelect;
+  mPchNvsAreaProtocol.Area->DAI2 = (UINT8)HdAudioDxeConfig->SndwConfig[2].DataOnActiveIntervalSelect;
+  mPchNvsAreaProtocol.Area->DAI3 = (UINT8)HdAudioDxeConfig->SndwConfig[3].DataOnActiveIntervalSelect;
+
+  mPchNvsAreaProtocol.Area->DOD0 = (UINT8)HdAudioDxeConfig->SndwConfig[0].DataOnDelaySelect;
+  mPchNvsAreaProtocol.Area->DOD1 = (UINT8)HdAudioDxeConfig->SndwConfig[1].DataOnDelaySelect;
+  mPchNvsAreaProtocol.Area->DOD2 = (UINT8)HdAudioDxeConfig->SndwConfig[2].DataOnDelaySelect;
+  mPchNvsAreaProtocol.Area->DOD3 = (UINT8)HdAudioDxeConfig->SndwConfig[3].DataOnDelaySelect;
+}
+
+/**
+  Initialize Intel High Definition Audio ACPI Tables
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_LOAD_ERROR          ACPI table cannot be installed
+  @retval EFI_UNSUPPORTED         ACPI table not set because DSP is disabled
+**/
+EFI_STATUS
+PchHdAudioAcpiInit (
+  VOID
+  )
+{
+  EFI_STATUS                    Status;
+  UINT64                        HdaPciBase;
+  CONST HDAUDIO_HOB             *HdAudioConfigHob;
+  PCH_POLICY_PROTOCOL           *PchPolicy;
+  HDAUDIO_DXE_CONFIG            *HdAudioDxeConfig;
+  NHLT_ACPI_TABLE               *NhltTable;
+
+
+  DEBUG ((DEBUG_INFO, "PchHdAudioAcpiInit() Start\n"));
+
+  HdAudioConfigHob = &mPchConfigHob->HdAudio;
+
+  ///
+  /// Get PCH Policy Protocol
+  ///
+  Status = gBS->LocateProtocol (&gPchPolicyProtocolGuid, NULL, (VOID **)&PchPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Get HD Audio DXE Config Block
+  ///
+  Status = GetConfigBlock ((VOID *)PchPolicy, &gHdAudioDxeConfigGuid, (VOID *)&HdAudioDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  HdaPciBase = HdaPciCfgBase ();
+
+  if ((PciSegmentRead16 (HdaPciBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) || (HdAudioConfigHob->DspEnable == FALSE)) {
+    // Do not set ACPI tables if HDAudio is Function disabled or DSP is disabled
+    DEBUG ((DEBUG_INFO, "AudioDSP: Non-HDAudio ACPI Table (NHLT) not set!\n"));
+    return EFI_UNSUPPORTED;
+  }
+
+  NhltTable = LocateNhltAcpiTable ();
+  if (NhltTable == NULL) {
+    return EFI_LOAD_ERROR;
+  }
+
+  UpdateHdaAcpiData ((UINT64) (UINTN) NhltTable, (UINT32) (NhltTable->Header.Length), HdAudioConfigHob, HdAudioDxeConfig);
+  DEBUG_CODE ( NhltAcpiTableDump (NhltTable); );
+
+  DEBUG ((DEBUG_INFO, "PchHdAudioAcpiInit() End - Status = %r\n", Status));
+  return Status;
+}
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchInit.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchInit.c
new file mode 100644
index 0000000000..734d4e295a
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchInit.c
@@ -0,0 +1,314 @@
+/** @file
+  This is the Common driver that initializes the Intel PCH.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/TimerLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/HobLib.h>
+
+#include "PchInit.h"
+#include <PchPolicyCommon.h>
+#include <Library/SpiCommonLib.h>
+#include <Library/PmcPrivateLib.h>
+#include <Library/PchDmiLib.h>
+#include <Library/SiScheduleResetLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PchPcrLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Library/SpiAccessPrivateLib.h>
+#include <Register/PchRegs.h>
+#include <Register/PchPcrRegs.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/SpiRegs.h>
+#include <Register/PchRegsPsth.h>
+#include <Register/PmcRegs.h>
+#include <Register/HdaRegs.h>
+#include <Library/GpioCheckConflictLib.h>
+#include <Library/PchPciBdfLib.h>
+#include <Library/PchInfoLib.h>
+
+//
+// Module variables
+//
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_CONFIG_HOB           *mPchConfigHob;
+
+//
+// EFI_EVENT
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_EVENT mHeciEvent;
+
+/**
+  Common PchInit Module Entry Point
+**/
+VOID
+PchInitEntryPointCommon (
+  VOID
+  )
+{
+  EFI_PEI_HOB_POINTERS  HobPtr;
+
+  DEBUG ((DEBUG_INFO, "PchInitEntryPointCommon() Start\n"));
+
+  //
+  // Get PCH Config HOB.
+  //
+  HobPtr.Guid   = GetFirstGuidHob (&gPchConfigHobGuid);
+  ASSERT (HobPtr.Guid != NULL);
+  mPchConfigHob = (PCH_CONFIG_HOB *) GET_GUID_HOB_DATA (HobPtr.Guid);
+
+  DEBUG ((DEBUG_INFO, "PchInitEntryPointCommon() End\n"));
+
+  return;
+}
+
+/**
+  Lock SPI register before boot
+**/
+VOID
+LockSpiConfiguration (
+  VOID
+  )
+{
+  UINTN         Index;
+  UINT16        Data16;
+  UINT16        Data16And;
+  UINT16        Data16Or;
+  UINT32        Data32;
+  UINT32        DlockValue;
+  UINT64        PciSpiRegBase;
+  UINT32        PchSpiBar0;
+  UINT32        Timer;
+
+  PciSpiRegBase = SpiPciCfgBase ();
+
+  //
+  // Check for SPI controller presence before programming
+  //
+  if (PciSegmentRead16 (PciSpiRegBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+    return;
+  }
+
+  //
+  // Make sure SPI BAR0 has fixed address before writing to boot script.
+  // The same base address is set in PEI and will be used during resume.
+  //
+  PchSpiBar0 = PCH_SPI_BASE_ADDRESS;
+
+  PciSegmentAnd8    (PciSpiRegBase + PCI_COMMAND_OFFSET, (UINT8) ~EFI_PCI_COMMAND_MEMORY_SPACE);
+  PciSegmentWrite32 (PciSpiRegBase + R_SPI_CFG_BAR0, PchSpiBar0);
+  PciSegmentOr8     (PciSpiRegBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
+
+  //
+  // Locking for security reasons only if Extended BIOS Range Decode is supported
+  //
+  if (IsExtendedBiosRangeDecodeSupported ()) {
+    //
+    // Before setting FLOCKDN lock Extended BIOS Range configuration
+    // All configuration of this feature shall be done already at this moment
+    //
+    PciSegmentOr32 (PciSpiRegBase + R_SPI_CFG_BC, BIT28);
+    S3BootScriptSavePciCfgWrite (
+      S3BootScriptWidthUint32,
+      (UINTN) PciSpiRegBase + R_SPI_CFG_BC,
+      1,
+      (VOID *) (UINTN) (PciSpiRegBase + R_SPI_CFG_BC)
+      );
+  }
+
+  //
+  // Program the Flash Protection Range Register based on policy
+  //
+  DlockValue = MmioRead32 (PchSpiBar0 + R_SPI_MEM_DLOCK);
+  for (Index = 0; Index < PCH_FLASH_PROTECTED_RANGES; ++Index) {
+    if ((mPchConfigHob->ProtectRange[Index].WriteProtectionEnable ||
+         mPchConfigHob->ProtectRange[Index].ReadProtectionEnable) != TRUE) {
+      continue;
+    }
+
+    //
+    // Proceed to program the register after ensure it is enabled
+    //
+    Data32 = 0;
+    Data32 |= (mPchConfigHob->ProtectRange[Index].WriteProtectionEnable == TRUE) ? B_SPI_MEM_PRX_WPE : 0;
+    Data32 |= (mPchConfigHob->ProtectRange[Index].ReadProtectionEnable == TRUE) ? B_SPI_MEM_PRX_RPE : 0;
+    Data32 |= ((UINT32) mPchConfigHob->ProtectRange[Index].ProtectedRangeLimit << N_SPI_MEM_PRX_PRL) & B_SPI_MEM_PRX_PRL_MASK;
+    Data32 |= ((UINT32) mPchConfigHob->ProtectRange[Index].ProtectedRangeBase << N_SPI_MEM_PRX_PRB) & B_SPI_MEM_PRX_PRB_MASK;
+    DEBUG ((DEBUG_INFO, "Protected range %d: 0x%08x \n", Index, Data32));
+
+    DlockValue |= (UINT32) (B_SPI_MEM_DLOCK_PR0LOCKDN << Index);
+    MmioWrite32 ((UINTN) (PchSpiBar0 + (R_SPI_MEM_PR0 + (Index * S_SPI_MEM_PRX))), Data32);
+    S3BootScriptSaveMemWrite (
+      S3BootScriptWidthUint32,
+      (UINTN) (PchSpiBar0 + (R_SPI_MEM_PR0 + (Index * S_SPI_MEM_PRX))),
+      1,
+      (VOID *) (UINTN) (PchSpiBar0 + (R_SPI_MEM_PR0 + (Index * S_SPI_MEM_PRX)))
+      );
+  }
+  //
+  // Program DLOCK register
+  //
+  MmioWrite32 ((UINTN) (PchSpiBar0 + R_SPI_MEM_DLOCK), DlockValue);
+  S3BootScriptSaveMemWrite (
+    S3BootScriptWidthUint32,
+    (UINTN) (PchSpiBar0 + R_SPI_MEM_DLOCK),
+    1,
+    (VOID *) (UINTN) (PchSpiBar0 + R_SPI_MEM_DLOCK)
+    );
+
+  ///
+  /// PCH BIOS Spec Section 3.6 Flash Security Recommendation
+  /// In PCH SPI controller the BIOS should set the Flash Configuration Lock-Down bit
+  /// (SPI_BAR0 + 04[15]) at end of post.  When set to 1, those Flash Program Registers
+  /// that are locked down by this FLOCKDN bit cannot be written.
+  /// Please refer to the EDS for which program registers are impacted.
+  /// Additionally BIOS must program SPI_BAR0 + 0x04 BIT11 (WRSDIS) to disable Write Status in HW sequencing
+  ///
+
+  //
+  // Ensure there is no pending SPI trasaction before setting lock bits
+  //
+  Timer = 0;
+  while (MmioRead16 (PchSpiBar0 + R_SPI_MEM_HSFSC) & B_SPI_MEM_HSFSC_SCIP) {
+    if (Timer > SPI_WAIT_TIME) {
+      //
+      // SPI transaction is pending too long at this point, exit with error.
+      //
+      DEBUG ((DEBUG_ERROR, "SPI Cycle timeout\n"));
+      ASSERT (FALSE);
+      break;
+    }
+    MicroSecondDelay (SPI_WAIT_PERIOD);
+    Timer += SPI_WAIT_PERIOD;
+  }
+
+  Data16And = B_SPI_MEM_HSFSC_SCIP;
+  Data16    = 0;
+  S3BootScriptSaveMemPoll (
+    S3BootScriptWidthUint16,
+    PchSpiBar0 + R_SPI_MEM_HSFSC,
+    &Data16And,
+    &Data16,
+    SPI_WAIT_PERIOD,
+    SPI_WAIT_TIME / SPI_WAIT_PERIOD
+    );
+
+  //
+  // Clear any outstanding status
+  //
+  Data16Or  = B_SPI_MEM_HSFSC_SAF_DLE
+            | B_SPI_MEM_HSFSC_SAF_ERROR
+            | B_SPI_MEM_HSFSC_AEL
+            | B_SPI_MEM_HSFSC_FCERR
+            | B_SPI_MEM_HSFSC_FDONE;
+  Data16And = 0xFFFF;
+  MmioAndThenOr16 (PchSpiBar0 + R_SPI_MEM_HSFSC, Data16And, Data16Or);
+  S3BootScriptSaveMemReadWrite (
+    S3BootScriptWidthUint16,
+    PchSpiBar0 + R_SPI_MEM_HSFSC,
+    &Data16Or,
+    &Data16And
+    );
+
+  //
+  // Set WRSDIS
+  //
+  Data16Or  = B_SPI_MEM_HSFSC_WRSDIS;
+  Data16And = 0xFFFF;
+  MmioAndThenOr16 (PchSpiBar0 + R_SPI_MEM_HSFSC, Data16And, Data16Or);
+  S3BootScriptSaveMemReadWrite (
+    S3BootScriptWidthUint16,
+    PchSpiBar0 + R_SPI_MEM_HSFSC,
+    &Data16Or,
+    &Data16And
+    );
+
+  //
+  // Set FLOCKDN
+  //
+  Data16Or  = B_SPI_MEM_HSFSC_FLOCKDN;
+  Data16And = 0xFFFF;
+  MmioAndThenOr16 (PchSpiBar0 + R_SPI_MEM_HSFSC, Data16And, Data16Or);
+  S3BootScriptSaveMemReadWrite (
+    S3BootScriptWidthUint16,
+    PchSpiBar0 + R_SPI_MEM_HSFSC,
+    &Data16Or,
+    &Data16And
+    );
+
+  ///
+  /// SPI Flash Programming Guide Section 5.5.2 Vendor Component Lock
+  /// It is strongly recommended that BIOS sets the Vendor Component Lock (VCL) bits. VCL applies
+  /// the lock to both VSCC0 and VSCC1 even if VSCC0 is not used. Without the VCL bits set, it is
+  /// possible to make Host/GbE VSCC register(s) changes in that can cause undesired host and
+  /// integrated GbE Serial Flash functionality.
+  ///
+  MmioOr32 ((UINTN) (PchSpiBar0 + R_SPI_MEM_SFDP0_VSCC0), B_SPI_MEM_SFDP0_VSCC0_VCL);
+  S3BootScriptSaveMemWrite (
+    S3BootScriptWidthUint32,
+    (UINTN) (PchSpiBar0 + R_SPI_MEM_SFDP0_VSCC0),
+    1,
+    (VOID *) (UINTN) (PchSpiBar0 + R_SPI_MEM_SFDP0_VSCC0)
+    );
+}
+
+/**
+  Set HD Audio PME bit
+**/
+VOID
+ConfigureHdAudioPme (
+  VOID
+  )
+{
+  UINT64 HdaPciBase;
+
+  HdaPciBase = HdaPciCfgBase ();
+
+  if (PciSegmentRead16 (HdaPciBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+    return;
+  }
+
+  ///
+  /// PME Enable for Audio controller
+  ///
+  if (mPchConfigHob->HdAudio.Pme == TRUE) {
+    PciSegmentOr32 (HdaPciBase + R_HDA_CFG_PCS, (UINT32) B_HDA_CFG_PCS_PMEE);
+  }
+}
+
+/**
+  Set eSPI BME bit
+**/
+VOID
+ConfigureEspiBme (
+  VOID
+  )
+{
+  UINT64 EspiPciBase;
+
+  EspiPciBase = EspiPciCfgBase ();
+
+  if (PciSegmentRead16 (EspiPciBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+    return;
+  }
+  if ((PciSegmentRead32 (EspiPciBase + R_ESPI_CFG_PCBC) & B_ESPI_CFG_PCBC_ESPI_EN) == 0) {
+    return;
+  }
+
+  //
+  // Refer to PCH BWG.
+  // To enable eSPI bus mastering BIOS must enable BME in eSPI controller
+  // and also set BME bit in the respective slave devices through Configuration
+  // and Capabilities register of each slave using Get_Configuration and Set_Configuration functionality.
+  //
+  // NOTE: The setting is also done in PEI, but might be cleared by PCI bus during PCI enumeration.
+  //       Therefore, reeable it after PCI enumeration done.
+  //
+  if (mPchConfigHob->Espi.BmeMasterSlaveEnabled == TRUE) {
+    PciSegmentOr8 (EspiPciBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_BUS_MASTER);
+  }
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchInit.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchInit.h
new file mode 100644
index 0000000000..0d6647e3f3
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchInit.h
@@ -0,0 +1,122 @@
+/** @file
+  Header file for PCH Initialization Driver.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_INIT_DXE_H_
+#define _PCH_INIT_DXE_H_
+
+#include <SiConfigHob.h>
+#include <PchConfigHob.h>
+#include <Protocol/PchNvsArea.h>
+
+//
+// Data definitions
+//
+extern EFI_HANDLE               mImageHandle;
+
+//
+// Pch NVS area definition
+//
+extern PCH_NVS_AREA_PROTOCOL    mPchNvsAreaProtocol;
+
+extern PCH_CONFIG_HOB           *mPchConfigHob;
+extern SI_CONFIG_HOB_DATA       *mSiConfigHobData;
+
+//
+// Function Prototype
+//
+
+//
+// Local function prototypes
+//
+/**
+  Common PchInit Module Entry Point
+**/
+VOID
+PchInitEntryPointCommon (
+  VOID
+  );
+
+/**
+  Calls Boot Os Hand off routine for each Serial IO Controller
+**/
+VOID
+ConfigureSerialIoAtBoot (
+  VOID
+  );
+
+/**
+  Puts all SerialIo controllers (except UARTs in debug mode) in D3.
+  Clears MemoryEnable for all PCI-mode controllers on S3 resume
+**/
+VOID
+ConfigureSerialIoAtS3Resume (
+  VOID
+  );
+
+/**
+  Add Serial Io UART Hidden Handles
+**/
+VOID
+CreateSerialIoUartHiddenHandle (
+  VOID
+  );
+
+/**
+  Initialize Intel High Definition Audio ACPI Tables
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_LOAD_ERROR          ACPI table cannot be installed
+  @retval EFI_UNSUPPORTED         ACPI table not set because DSP is disabled
+**/
+EFI_STATUS
+PchHdAudioAcpiInit (
+  VOID
+  );
+
+/**
+  Perform the remaining configuration on SATA to perform device detection,
+  then set the SATA SPD and PxE corresponding, and set the Register Lock on PCH SATA
+**/
+VOID
+ConfigureSataOnEndOfDxe (
+  VOID
+  );
+
+/**
+  Update ASL data for CNVI Device.
+
+  @retval EFI_SUCCESS             The function completed successfully
+**/
+EFI_STATUS
+UpdateCnviAcpiData (
+   VOID
+   );
+
+/**
+  Initialize Pch acpi
+  @param[in] ImageHandle          Handle for the image of this driver
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+PchAcpiInit (
+  IN EFI_HANDLE         ImageHandle
+  );
+
+/**
+  Update ASL object before Boot
+
+  @retval EFI_STATUS
+  @retval EFI_NOT_READY         The Acpi protocols are not ready.
+**/
+EFI_STATUS
+PchUpdateNvsArea (
+  VOID
+  );
+
+#endif // _PCH_INIT_DXE_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxe.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxe.c
new file mode 100644
index 0000000000..1d4f08a86c
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxe.c
@@ -0,0 +1,354 @@
+/** @file
+  This is the Uefi driver that initializes the Intel PCH.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#include "PchInit.h"
+#include <PchPolicyCommon.h>
+#include <Protocol/PcieIoTrap.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PmcLib.h>
+#include <Library/PchPcieRpLib.h>
+#include <Library/PmcPrivateLib.h>
+#include <Library/PciExpressHelpersLib.h>
+#include <PcieRegs.h>
+#include <Register/PchPcieRpRegs.h>
+#include <Register/PmcRegs.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_HANDLE               mImageHandle;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16                   mPcieIoTrapAddress;
+
+VOID
+EFIAPI
+PchOnBootToOs (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  );
+
+
+VOID
+EFIAPI
+PchOnExitBootServices (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  );
+
+
+VOID
+EFIAPI
+PchOnReadyToBoot (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  );
+
+/**
+  Process all the lock downs
+**/
+VOID
+ProcessSmiLocks (
+  VOID
+  )
+{
+  UINT32        Data32And;
+  UINT32        Data32Or;
+  UINT16        ABase;
+
+  ///
+  /// PCH BIOS Spec Section 3.6 Flash Security Recommendation
+  /// BIOS needs to enables SMI_LOCK (PMC PCI offset A0h[4] = 1b) which prevent writes
+  /// to the Global SMI Enable bit (GLB_SMI_EN ABASE + 30h[0]). Enabling this bit will
+  /// mitigate malicious software attempts to gain system management mode privileges.
+  ///
+  if (mPchConfigHob->LockDown.GlobalSmi == TRUE) {
+    ///
+    /// Save Global SMI Enable bit setting before BIOS enables SMI_LOCK during S3 resume
+    ///
+    ABase = PmcGetAcpiBase ();
+    Data32Or = IoRead32 ((UINTN) (ABase + R_ACPI_IO_SMI_EN));
+    if ((Data32Or & B_ACPI_IO_SMI_EN_GBL_SMI) != 0) {
+      Data32And = 0xFFFFFFFF;
+      Data32Or |= B_ACPI_IO_SMI_EN_GBL_SMI;
+      S3BootScriptSaveIoReadWrite (
+        S3BootScriptWidthUint32,
+        (UINTN) (ABase + R_ACPI_IO_SMI_EN),
+        &Data32Or,  // Data to be ORed
+        &Data32And  // Data to be ANDed
+        );
+    }
+      PmcLockSmiWithS3BootScript ();
+  }
+}
+
+/**
+  Do PCIE power management while resume from S3
+**/
+VOID
+ReconfigurePciePowerManagementForS3 (
+  VOID
+  )
+{
+  EFI_STATUS                            Status;
+  UINT32                                Data32;
+  PCH_PCIE_IOTRAP_PROTOCOL              *PchPcieIoTrapProtocol;
+
+  Status = gBS->LocateProtocol (&gPchPcieIoTrapProtocolGuid, NULL, (VOID **) &PchPcieIoTrapProtocol);
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+  mPcieIoTrapAddress = PchPcieIoTrapProtocol->PcieTrapAddress;
+  DEBUG ((DEBUG_INFO, "PcieIoTrapAddress: %0x\n", mPcieIoTrapAddress));
+
+  if (mPcieIoTrapAddress != 0) {
+    //
+    // Save PCH PCIE IoTrap address to re-config PCIE power management setting after resume from S3
+    //
+    Data32 = PchPciePmTrap;
+    S3BootScriptSaveIoWrite (
+      S3BootScriptWidthUint32,
+      (UINTN) (mPcieIoTrapAddress),
+      1,
+      &Data32
+      );
+  } else {
+    ASSERT (FALSE);
+  }
+}
+
+/**
+  This is the callback function for PCI ENUMERATION COMPLETE.
+**/
+VOID
+EFIAPI
+PchOnPciEnumComplete (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  )
+{
+  EFI_STATUS          Status;
+  VOID                *ProtocolPointer;
+
+  ///
+  /// Check if this is first time called by EfiCreateProtocolNotifyEvent() or not,
+  /// if it is, we will skip it until real event is triggered
+  ///
+  Status = gBS->LocateProtocol (&gEfiPciEnumerationCompleteProtocolGuid, NULL, (VOID **) &ProtocolPointer);
+  if (EFI_SUCCESS != Status) {
+    return;
+  }
+  gBS->CloseEvent (Event);
+
+  ReconfigurePciePowerManagementForS3 ();
+  ProcessSmiLocks ();
+  ConfigureSerialIoAtS3Resume ();
+}
+
+/**
+  Register callback functions for PCH DXE.
+**/
+VOID
+PchRegisterNotifications (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+  EFI_EVENT   ReadyToBoot;
+  EFI_EVENT   LegacyBootEvent;
+  EFI_EVENT   ExitBootServicesEvent;
+  VOID        *Registration;
+
+  ///
+  /// Create PCI Enumeration Completed callback for PCH
+  ///
+  EfiCreateProtocolNotifyEvent (
+    &gEfiPciEnumerationCompleteProtocolGuid,
+    TPL_CALLBACK,
+    PchOnPciEnumComplete,
+    NULL,
+    &Registration
+    );
+
+  //
+  // Register a Ready to boot event to config PCIE power management setting after OPROM executed
+  //
+  Status = EfiCreateEventReadyToBootEx (
+             TPL_CALLBACK,
+             PchOnReadyToBoot,
+             NULL,
+             &ReadyToBoot
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Create events for PCH to do the task before ExitBootServices/LegacyBoot.
+  // It is guaranteed that only one of two events below will be signalled
+  //
+  Status = gBS->CreateEvent (
+                  EVT_SIGNAL_EXIT_BOOT_SERVICES,
+                  TPL_CALLBACK,
+                  PchOnExitBootServices,
+                  NULL,
+                  &ExitBootServicesEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = EfiCreateEventLegacyBootEx (
+             TPL_CALLBACK,
+             PchOnBootToOs,
+             NULL,
+             &LegacyBootEvent
+             );
+  ASSERT_EFI_ERROR (Status);
+}
+
+/**
+  <b>PchInit DXE Module Entry Point</b>\n
+  - <b>Introduction</b>\n
+      The PchInit module is a DXE driver that initializes the Intel Platform Controller Hub
+      following the PCH BIOS specification and EDS requirements and recommendations. It consumes
+      the PCH_POLICY_HOB SI_POLICY_HOB for expected configurations per policy.
+      This is the standard EFI driver point that detects whether there is an supported PCH in
+      the system and if so, initializes the chipset.
+
+  - <b>Details</b>\n
+    This module is required for initializing the Intel Platform Controller Hub to
+    follow the PCH BIOS specification and EDS.
+    This includes some initialization sequences, enabling and disabling PCH devices,
+    configuring clock gating, RST PCIe Storage Remapping, SATA controller, ASPM of PCIE devices. Right before end of DXE,
+    it's responsible to lock down registers for security requirement.
+
+  - @pre
+    - PCH PCR base address configured
+    - EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+      - This is to ensure that PCI MMIO and IO resource has been prepared and available for this driver to allocate.
+
+  - @result
+    - Publishes the @link _PCH_INFO_PROTOCOL PCH_INFO_PROTOCOL @endlink
+    - Publishes the @link _PCH_EMMC_TUNING_PROTOCOL PCH_EMMC_TUNING_PROTOCOL @endlink
+
+  - <b>References</b>\n
+    - @link _PCH_POLICY PCH_POLICY_HOB @endlink.
+    - @link _SI_POLICY_STRUCT SI_POLICY_HOB @endlink.
+
+  - <b>Integration Checklists</b>\n
+    - Verify prerequisites are met. Porting Recommendations.
+    - No modification of this module should be necessary
+    - Any modification of this module should follow the PCH BIOS Specification and EDS
+
+  @param[in] ImageHandle          Handle for the image of this driver
+  @param[in] SystemTable          Pointer to the EFI System Table
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+PchInitEntryPointDxe (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS            Status;
+
+  DEBUG ((DEBUG_INFO, "PchInitEntryPointDxe() Start\n"));
+
+  mImageHandle = ImageHandle;
+
+  PchInitEntryPointCommon ();
+
+  Status = PchAcpiInit (ImageHandle);
+
+  PchRegisterNotifications ();
+
+  CreateSerialIoUartHiddenHandle ();
+
+  DEBUG ((DEBUG_INFO, "PchInitEntryPointDxe() End\n"));
+
+  return Status;
+}
+
+/**
+  PCH initialization before ExitBootServices / LegacyBoot events
+  Useful for operations which must happen later than at EndOfPost event
+
+  @param[in] Event                A pointer to the Event that triggered the callback.
+  @param[in] Context              A pointer to private data registered with the callback function.
+**/
+VOID
+EFIAPI
+PchOnBootToOs (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  )
+{
+  ///
+  /// Closed the event to avoid call twice
+  ///
+  if (Event != NULL) {
+    gBS->CloseEvent (Event);
+  }
+
+  ConfigureSerialIoAtBoot ();
+
+  return;
+}
+
+/**
+  PCH initialization on ExitBootService. This event is used if only ExitBootService is used
+  and not in legacy boot
+
+  @param[in] Event                A pointer to the Event that triggered the callback.
+  @param[in] Context              A pointer to private data registered with the callback function.
+
+  @retval None
+**/
+VOID
+EFIAPI
+PchOnExitBootServices (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  )
+{
+  PchOnBootToOs (NULL, NULL);
+
+  return;
+}
+
+/**
+  PCH initialization before boot to OS
+
+  @param[in] Event                A pointer to the Event that triggered the callback.
+  @param[in] Context              A pointer to private data registered with the callback function.
+**/
+VOID
+EFIAPI
+PchOnReadyToBoot (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  )
+{
+  DEBUG ((DEBUG_INFO, "Uefi PchOnReadyToBoot() Start\n"));
+
+  if (Event != NULL) {
+    gBS->CloseEvent (Event);
+  }
+
+  //
+  // Trigger an Iotrap SMI to config PCIE power management setting after PCI enumrate is done
+  //
+  if (mPcieIoTrapAddress != 0) {
+    IoWrite32 ((UINTN) mPcieIoTrapAddress, PchPciePmTrap);
+  } else {
+    ASSERT (FALSE);
+  }
+
+  DEBUG ((DEBUG_INFO, "Uefi PchOnReadyToBoot() End\n"));
+}
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeTgl.inf b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeTgl.inf
new file mode 100644
index 0000000000..4941ff0f49
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeTgl.inf
@@ -0,0 +1,96 @@
+## @file
+# Component description file for Pch Initialization driver
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PchInitDxeTgl
+FILE_GUID = 4BD0EB2F-3A2D-442E-822D-753516F75424
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_DRIVER
+ENTRY_POINT = PchInitEntryPointDxe
+
+
+[LibraryClasses]
+S3BootScriptLib
+PchCycleDecodingLib
+PchPcieRpLib
+PchPcrLib
+PchInfoLib
+PciExpressHelpersLib
+UefiBootServicesTableLib
+DebugLib
+IoLib
+TimerLib
+HobLib
+BaseMemoryLib
+MemoryAllocationLib
+UefiLib
+DxeServicesTableLib
+UefiDriverEntryPoint
+UefiRuntimeServicesTableLib
+GpioLib
+SerialIoAccessLib
+ConfigBlockLib
+PmcLib
+PmcPrivateLibWithS3
+SataLib
+PchDmiWithS3Lib
+GbeLib
+SiScheduleResetLib
+DxeHdaNhltLib
+SpiAccessPrivateLib
+PchPciBdfLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+gSiPkgTokenSpaceGuid.PcdSiPciExpressBaseAddress
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempMemBaseAddr ## CONSUMES
+gSiPkgTokenSpaceGuid.PcdEmbeddedEnable             ## CONSUMES
+
+[Sources]
+PchInitDxe.c
+PchInit.h
+PchInit.c
+PchSata.c
+PchSerialIo.c
+PchSerialIoDxe.c
+PchHdaAcpi.c
+PchCnviAcpi.c
+PchAcpi.c
+
+
+[Protocols]
+gPchNvsAreaProtocolGuid ## PRODUCES
+gEfiPciIoProtocolGuid ## CONSUMES
+gEfiAcpiTableProtocolGuid ## CONSUMES
+gEfiBlockIoProtocolGuid ## CONSUMES
+gHeciProtocolGuid
+gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES
+gPchPcieIoTrapProtocolGuid ## CONSUMES
+gPchPolicyProtocolGuid ## CONSUMES
+
+
+[Guids]
+gEfiEndOfDxeEventGroupGuid
+gEfiAcpiTableGuid
+gEmmcDxeConfigGuid               ## CONSUMES
+gSiConfigHobGuid                 ## CONSUMES
+gPchConfigHobGuid                ## CONSUMES
+gPchRstHobGuid                   ## CONSUMES
+gHdAudioDxeConfigGuid            ## CONSUMES
+gGpioDxeConfigGuid               ## CONSUMES
+gCnviConfigHobGuid               ## CONSUMES
+gHybridStorageHobGuid            ## CONSUMES
+
+[Depex]
+gEfiPciHostBridgeResourceAllocationProtocolGuid ## This is to ensure that PCI MMIO and IO resource has been prepared and available for this driver to allocate.
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchSata.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchSata.c
new file mode 100644
index 0000000000..886f3b4bc0
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchSata.c
@@ -0,0 +1,89 @@
+/** @file
+  Perform related functions for PCH Sata in DXE phase
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/S3BootScriptLib.h>
+
+#include "PchInit.h"
+#include <Library/SataLib.h>
+#include <Library/PchPciBdfLib.h>
+#include <Register/SataRegs.h>
+
+/**
+  Perform the remaining configuration on SATA to perform device detection,
+  then set the SATA SPD and PxE corresponding, and set the Register Lock on PCH SATA
+
+  @retval None
+**/
+VOID
+ConfigureSataOnEndOfDxe (
+  VOID
+  )
+{
+  UINT64        PciSataRegBase;
+  UINT16        SataPortsEnabled;
+  UINT32        DwordReg;
+  UINTN         Index;
+  UINT32        SataCtrlIndex;
+
+  for (SataCtrlIndex = 0; SataCtrlIndex < MaxSataControllerNum (); SataCtrlIndex++) {
+    ///
+    /// SATA PCS: Enable the port in any of below condition:
+    /// i.)   Hot plug is enabled
+    /// ii.)  A device is attached
+    /// iii.) Test mode is enabled
+    /// iv.)  Configured as eSATA port
+    ///
+    PciSataRegBase    = SataPciCfgBase (SataCtrlIndex);
+    SataPortsEnabled  = 0;
+
+    DwordReg = PciSegmentRead32 (PciSataRegBase + R_SATA_CFG_PCS);
+    for (Index = 0; Index < MaxSataPortNum (SataCtrlIndex); Index++) {
+      if ((mPchConfigHob->Sata[SataCtrlIndex].PortSettings[Index].HotPlug == TRUE) ||
+          (DwordReg & (B_SATA_CFG_PCS_P0P << Index)) ||
+            (mPchConfigHob->Sata[SataCtrlIndex].TestMode == TRUE) ||
+            (mPchConfigHob->Sata[SataCtrlIndex].PortSettings[Index].External == TRUE)) {
+          SataPortsEnabled |= (mPchConfigHob->Sata[SataCtrlIndex].PortSettings[Index].Enable << Index);
+      }
+    }
+
+    ///
+    /// Set MAP."Sata PortX Disable", SATA PCI offset 90h[23:16] to 1b if SATA Port 0/1/2/3/4/5/6/7 is disabled
+    ///
+    PciSegmentOr32 (PciSataRegBase + R_SATA_CFG_MAP, (~SataPortsEnabled << N_SATA_CFG_MAP_SPD));
+    S3BootScriptSaveMemWrite (
+      S3BootScriptWidthUint32,
+      PcdGet64 (PcdSiPciExpressBaseAddress) + PciSataRegBase + R_SATA_CFG_MAP,
+      1,
+      (VOID *) (UINTN) (PcdGet64 (PcdSiPciExpressBaseAddress) + PciSataRegBase + R_SATA_CFG_MAP)
+      );
+
+    ///
+    /// Program PCS "Port X Enabled", SATA PCI offset 94h[7:0] = Port 0~7 Enabled bit as per SataPortsEnabled value.
+    ///
+    PciSegmentOr16 (PciSataRegBase + R_SATA_CFG_PCS, SataPortsEnabled);
+    S3BootScriptSaveMemWrite (
+      S3BootScriptWidthUint16,
+      PcdGet64 (PcdSiPciExpressBaseAddress) + PciSataRegBase + R_SATA_CFG_PCS,
+      1,
+      (VOID *) (UINTN) (PcdGet64 (PcdSiPciExpressBaseAddress) + PciSataRegBase + R_SATA_CFG_PCS)
+      );
+
+    ///
+    /// Step 14
+    /// Program SATA PCI offset 9Ch [31] to 1b
+    ///
+    PciSegmentOr32 ((UINTN) (PciSataRegBase + R_SATA_CFG_SATAGC), BIT31);
+    S3BootScriptSaveMemWrite (
+      S3BootScriptWidthUint32,
+      PcdGet64 (PcdSiPciExpressBaseAddress) + PciSataRegBase + R_SATA_CFG_SATAGC,
+      1,
+      (VOID *) (UINTN) (PcdGet64 (PcdSiPciExpressBaseAddress) + PciSataRegBase + R_SATA_CFG_SATAGC)
+      );
+  }
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIo.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIo.c
new file mode 100644
index 0000000000..9409a9a387
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIo.c
@@ -0,0 +1,33 @@
+/** @file
+  Initializes Serial IO Controllers.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "PchInit.h"
+#include <Library/SerialIoPrivateLib.h>
+#include <Library/PchInfoLib.h>
+
+/**
+  Calls Boot Os Hand off routine for each Serial IO Controller
+**/
+VOID
+ConfigureSerialIoAtBoot (
+  VOID
+  )
+{
+  UINT8  Index;
+
+  for (Index = 0; Index < GetPchMaxSerialIoSpiControllersNum (); Index++) {
+    SerialIoSpiBootHandler (Index, &mPchConfigHob->SerialIo.SpiDeviceConfig[Index]);
+  }
+
+  for (Index = 0; Index < GetPchMaxSerialIoI2cControllersNum (); Index++) {
+    SerialIoI2cBootHandler (Index, &mPchConfigHob->SerialIo.I2cDeviceConfig[Index]);
+  }
+
+  for (Index = 0; Index < GetPchMaxSerialIoUartControllersNum (); Index++) {
+    SerialIoUartBootHandler (Index, &mPchConfigHob->SerialIo.UartDeviceConfig[Index]);
+  }
+}
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIoDxe.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIoDxe.c
new file mode 100644
index 0000000000..fde7da6b96
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIoDxe.c
@@ -0,0 +1,134 @@
+/** @file
+  Initializes Serial IO Controllers.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/SerialIoPrivateLib.h>
+#include <Library/PchInfoLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Register/SerialIoRegs.h>
+#include <PchInit.h>
+
+typedef struct {
+  ACPI_HID_DEVICE_PATH          RootPort;
+  ACPI_EXTENDED_HID_DEVICE_PATH AcpiDev;
+  CHAR8                         HidString[8];
+  UINT16                        DeviceId;
+  UINT8                         UartIndex;
+  EFI_DEVICE_PATH_PROTOCOL      End;
+} SERIALIO_UART_DEVICE_PATH;
+
+#define mPciRootBridge {{ACPI_DEVICE_PATH, ACPI_DP, {(UINT8)(sizeof (ACPI_HID_DEVICE_PATH)), 0}}, EISA_PNP_ID (0x0A03), 0}
+#define mAcpiDev {{ACPI_DEVICE_PATH, ACPI_EXTENDED_DP, {(UINT8)(sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + (sizeof(CHAR8) * 8) + sizeof (UINT16) + sizeof (UINT8)), 0}},0,0,0}
+#define mEndEntire {END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, {END_DEVICE_PATH_LENGTH, 0}}
+
+GLOBAL_REMOVE_IF_UNREFERENCED SERIALIO_UART_DEVICE_PATH mSerialIoUartPath = {
+  mPciRootBridge,
+  mAcpiDev,
+  "UART\0\0\0",
+  0xFFFF,
+  0xFF,
+  mEndEntire
+};
+
+/**
+  Add Serial Io UART Hidden Handles
+**/
+VOID
+CreateSerialIoUartHiddenHandle (
+  VOID
+  )
+{
+  EFI_HANDLE               NewHandle;
+  EFI_DEVICE_PATH_PROTOCOL *NewPath;
+  EFI_STATUS               Status;
+  UINT8                    Index;
+  UINT16                   DeviceId;
+
+  DEBUG ((DEBUG_INFO, "CreateSerialIoUartHandle\n"));
+
+  for (Index = 0; Index < GetPchMaxSerialIoUartControllersNum (); Index++) {
+    DEBUG ((DEBUG_INFO, "UART Index: %d Mode: %d\n", Index, mPchConfigHob->SerialIo.UartDeviceConfig[Index].Mode));
+    if (mPchConfigHob->SerialIo.UartDeviceConfig[Index].Mode == SerialIoUartHidden) {
+      NewHandle = NULL;
+      DeviceId = MmioRead16 (GetSerialIoUartFixedPciCfgAddress (Index) + PCI_DEVICE_ID_OFFSET);
+      DEBUG ((DEBUG_INFO, "Creating Handle for UART DEVICE_ID: 0x%X \n", DeviceId));
+      mSerialIoUartPath.AcpiDev.HID  = 0x5432 + (Index << 16); //UAR
+      mSerialIoUartPath.HidString[4] = (CHAR8)('0' + Index);
+      mSerialIoUartPath.DeviceId     = DeviceId;
+      mSerialIoUartPath.UartIndex    = Index;
+      NewPath = DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL*) &mSerialIoUartPath);
+      Status = gBS->InstallMultipleProtocolInterfaces (
+                      &NewHandle,
+                      &gEfiDevicePathProtocolGuid,
+                      NewPath,
+                      NULL
+                      );
+      DEBUG ((DEBUG_INFO, "CreateSerialIoUartHandle Status: %r\n", Status));
+    }
+  }
+}
+
+/**
+  Stores Pme Control Status and Command register values in S3 Boot Script
+
+  @param[in] S3PciCfgBase      S3 Boot Script Pci Config Base
+  @param[in] Command           Pci Command register data to save
+  @param[in] Pme               Pci Pme Control register data to save
+
+**/
+VOID
+STATIC
+SerialIoS3Save (
+  IN UINTN   S3PciCfgBase,
+  IN UINTN   Command,
+  IN UINTN   Pme
+  )
+{
+  if (S3PciCfgBase != 0) {
+    S3BootScriptSavePciCfgWrite (S3BootScriptWidthUint32, S3PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, 1, &Pme);
+    S3BootScriptSavePciCfgWrite (S3BootScriptWidthUint32, S3PciCfgBase + PCI_COMMAND_OFFSET, 1, &Command);
+  }
+}
+
+/**
+  Puts all SerialIo controllers (except UARTs in debug mode) in D3.
+  Clears MemoryEnable for all PCI-mode controllers on S3 resume
+**/
+VOID
+ConfigureSerialIoAtS3Resume (
+  VOID
+  )
+{
+  UINT8     Index;
+  UINTN     S3PciCfgBase;
+  UINT32    Command;
+  UINT32    Pme;
+
+  S3PciCfgBase = 0;
+  for (Index = 0; Index < GetPchMaxSerialIoSpiControllersNum (); Index++) {
+    SerialIoSpiS3Handler (Index, &mPchConfigHob->SerialIo.SpiDeviceConfig[Index], &S3PciCfgBase, &Command, &Pme);
+    SerialIoS3Save (S3PciCfgBase, Command, Pme);
+  }
+
+  S3PciCfgBase = 0;
+  for (Index = 0; Index < GetPchMaxSerialIoI2cControllersNum (); Index++) {
+    SerialIoI2cS3Handler (Index, &mPchConfigHob->SerialIo.I2cDeviceConfig[Index], &S3PciCfgBase, &Command, &Pme);
+    SerialIoS3Save (S3PciCfgBase, Command, Pme);
+  }
+
+  S3PciCfgBase = 0;
+  for (Index = 0; Index < GetPchMaxSerialIoUartControllersNum (); Index++) {
+    SerialIoUartS3Handler (Index, &mPchConfigHob->SerialIo.UartDeviceConfig[Index], &S3PciCfgBase, &Command, &Pme);
+    SerialIoS3Save (S3PciCfgBase, Command, Pme);
+  }
+}
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/GbeSxSmm.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/GbeSxSmm.c
new file mode 100644
index 0000000000..786ce13915
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/GbeSxSmm.c
@@ -0,0 +1,266 @@
+/** @file
+  Gbe Sx handler implementation.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/TimerLib.h>
+#include "PchInitSmm.h"
+#include <Library/PmcPrivateLib.h>
+#include <Library/GbeMdiLib.h>
+#include <Library/GbeLib.h>
+#include <Register/PchRegs.h>
+#include <Register/GbeRegs.h>
+#include <Library/PchPciBdfLib.h>
+
+
+/**
+  Configure WOL during Sx entry.
+
+  @param [in]  GbeBar   GbE MMIO space
+**/
+VOID
+GbeWolWorkaround (
+  IN      UINT32  GbeBar
+  )
+{
+  UINT32      RAL0;
+  UINT32      RAH0;
+  UINT16      WUC;
+  EFI_STATUS  Status;
+  UINT16      Data16;
+
+  //
+  // 1. Set page to 769 Port Control Registers
+  // 2. Wait 4 mSec
+  //
+  Status = GbeMdiSetPage (GbeBar, PHY_MDI_PAGE_769_PORT_CONTROL_REGISTERS);
+  if (EFI_ERROR (Status)) return;
+
+  //
+  // 3. Set registry to 17 Port General Configuration
+  // 4. Copy all settings from Port General Configuration
+  //
+  Status = GbeMdiRead (GbeBar, B_PHY_MDI_PHY_ADDRESS_01, MDI_REG_SHIFT (R_PHY_MDI_PAGE_769_REGISETER_17_PGC), &Data16);
+  if (EFI_ERROR (Status)) return;
+
+  //
+  // 5. Modify BIT 4 and BIT 2 to disable host wake up and set MACPD
+  //
+  Status = GbeMdiWrite (GbeBar, B_PHY_MDI_PHY_ADDRESS_01, MDI_REG_SHIFT (R_PHY_MDI_PAGE_769_REGISETER_17_PGC), (Data16 | B_PHY_MDI_PAGE_769_REGISETER_17_PGC_MACPD_ENABLE) & (~B_PHY_MDI_PAGE_769_REGISETER_17_PGC_HOST_WAKE_UP));
+  if (EFI_ERROR (Status)) return;
+
+  //
+  // 6. Read Receive Address Low and Receive Address High from MMIO
+  //
+  RAL0 = MmioRead32 (GbeBar + R_GBE_MEM_CSR_RAL);
+  RAH0 = MmioRead32 (GbeBar + R_GBE_MEM_CSR_RAH);
+
+  //
+  // 7. Set page to 800 Wake Up Registers
+  // 8. Wait 4 mSec
+  //
+  Status = GbeMdiSetPage (GbeBar, PHY_MDI_PAGE_800_WAKE_UP_REGISTERS);
+  if (EFI_ERROR (Status)) return;
+
+  //
+  // 9. Set registry to 16 Receive Address Low 1/2
+  //
+  Status = GbeMdiSetRegister (GbeBar, R_PHY_MDI_PAGE_800_REGISETER_16_RAL0);
+  if (EFI_ERROR (Status)) return;
+
+  //
+  // 10. Program first 16 bits [0:15] out of 48 in Receive Address Low 1/2
+  //
+  Status = GbeMdiWrite (GbeBar, B_PHY_MDI_PHY_ADDRESS_01, R_PHY_MDI_PHY_REG_DATA_READ_WRITE, (RAL0 & 0xFFFF));
+  if (EFI_ERROR (Status)) return;
+
+  //
+  // 11. Set registry to 17 Receive Address Low 2/2
+  //
+  Status = GbeMdiSetRegister (GbeBar, R_PHY_MDI_PAGE_800_REGISETER_17_RAL1);
+  if (EFI_ERROR (Status)) return;
+
+  //
+  // 12. Program second 16 bits [16:31] out of 48 in Receive Address Low 2/2
+  //
+  Status = GbeMdiWrite (GbeBar, B_PHY_MDI_PHY_ADDRESS_01, R_PHY_MDI_PHY_REG_DATA_READ_WRITE, (RAL0 >> 16));
+  if (EFI_ERROR (Status)) return;
+
+  //
+  // 13. Set registry to 18 Receive Address High 1/2
+  //
+  Status = GbeMdiSetRegister (GbeBar, R_PHY_MDI_PAGE_800_REGISETER_18_RAH0);
+  if (EFI_ERROR (Status)) return;
+
+  //
+  // 14. Program last 16 bits [32:47] out of 48
+  //
+  Status = GbeMdiWrite (GbeBar, B_PHY_MDI_PHY_ADDRESS_01, R_PHY_MDI_PHY_REG_DATA_READ_WRITE, (RAH0 & B_GBE_MEM_CSR_RAH_RAH));
+  if (EFI_ERROR (Status)) return;
+
+  //
+  // 15. Set registry to 19 Receive Address High 2/2
+  //
+  Status = GbeMdiSetRegister (GbeBar, R_PHY_MDI_PAGE_800_REGISETER_19_RAH1);
+  if (EFI_ERROR (Status)) return;
+
+  //
+  // 16. Set Address Valid
+  //
+  Status = GbeMdiWrite (GbeBar, B_PHY_MDI_PHY_ADDRESS_01, R_PHY_MDI_PHY_REG_DATA_READ_WRITE, B_PHY_MDI_PAGE_800_REGISETER_19_RAH1_ADDRESS_VALID);
+  if (EFI_ERROR (Status)) return;
+
+  //
+  // 17. Set Wake Up Control Register 1
+  //
+  Status = GbeMdiSetRegister (GbeBar, R_PHY_MDI_PAGE_800_REGISETER_1_WUC);
+  if (EFI_ERROR (Status)) return;
+
+  //
+  // 18. Copy WakeUp Control from MAC MMIO
+  //
+  WUC = (UINT16) MmioRead32 (GbeBar + R_GBE_MEM_CSR_WUC);
+
+  //
+  // 19. Store WakeUp Contorl into LCD
+  // Modify APME bit to enable APM wake up
+  //
+  Status = GbeMdiWrite (GbeBar, B_PHY_MDI_PHY_ADDRESS_01, R_PHY_MDI_PHY_REG_DATA_READ_WRITE, (WUC & 0xFFFF));
+  if (EFI_ERROR (Status)) return;
+
+  //
+  // 20. Set page to 803 Host Wol Packet
+  // 21. Wait 4 mSec
+  //
+  Status = GbeMdiSetPage (GbeBar, PHY_MDI_PAGE_803_HOST_WOL_PACKET);
+  if (EFI_ERROR (Status)) return;
+
+  //
+  // 22. Set registry to 66 Host WoL Packet Clear
+  //
+  Status = GbeMdiSetRegister (GbeBar, R_PHY_MDI_PAGE_803_REGISETER_66_HWPC);
+  if (EFI_ERROR (Status)) return;
+
+  //
+  // 23. Clear WOL Packet
+  //
+  Status = GbeMdiWrite (GbeBar, B_PHY_MDI_PHY_ADDRESS_01, R_PHY_MDI_PHY_REG_DATA_READ_WRITE, 0);
+  if (EFI_ERROR (Status)) return;
+  //
+  // 24. Set page to 769 Port Control Registers
+  // 25. Wait 4 mSec
+  //
+  Status = GbeMdiSetPage (GbeBar, PHY_MDI_PAGE_769_PORT_CONTROL_REGISTERS);
+  if (EFI_ERROR (Status)) return;
+
+  //
+  // 26. Set registry to 17 Port General Configuration
+  //
+  Status = GbeMdiSetRegister (GbeBar, R_PHY_MDI_PAGE_769_REGISETER_17_PGC);
+  if (EFI_ERROR (Status)) return;
+
+  //
+  // 27. Copy all settings from Port General Configuration
+  //
+  Status = GbeMdiRead (GbeBar, B_PHY_MDI_PHY_ADDRESS_01, MDI_REG_SHIFT (R_PHY_MDI_PAGE_769_REGISETER_17_PGC), &Data16);
+  if (EFI_ERROR (Status)) return;
+
+  //
+  // 28. Modify BIT 4 and BIT 2 to enable host wake up and clear MACPD
+  //
+  Status = GbeMdiWrite (GbeBar, B_PHY_MDI_PHY_ADDRESS_01, MDI_REG_SHIFT (R_PHY_MDI_PAGE_769_REGISETER_17_PGC), (Data16 | B_PHY_MDI_PAGE_769_REGISETER_17_PGC_HOST_WAKE_UP) & (~B_PHY_MDI_PAGE_769_REGISETER_17_PGC_MACPD_ENABLE));
+  if (EFI_ERROR (Status)) return;
+}
+
+/**
+  Additional Internal GbE Controller special cases WOL Support.
+
+  System BIOS is required perform additional steps upon S0 to S3,4,5 transition
+  when ME is off and GbE device in D0. This is needed to enable LAN wake
+  in particular when platform is shut-down from EFI.
+**/
+VOID
+GbeSxWorkaround (
+  VOID
+  )
+{
+  UINT64      LanRegBase;
+  UINT32      GbeBar;
+  EFI_STATUS  Status;
+
+  LanRegBase = GbePciCfgBase ();
+
+  if (PciSegmentRead16 (LanRegBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+    return;
+  }
+
+  //
+  // Check if GbE device is in D0
+  //
+  if ((PciSegmentRead16 (LanRegBase + R_GBE_CFG_PMCS) & B_GBE_CFG_PMCS_PS) != V_GBE_CFG_PMCS_PS0) {
+    return;
+  }
+
+  ASSERT (mResvMmioSize >= (1 << N_GBE_CFG_MBARA_ALIGN));
+  GbeBar = (UINT32) mResvMmioBaseAddr;
+  if (GbeBar == 0) {
+    ASSERT (FALSE);
+    return;
+  }
+
+  //
+  // Enable MMIO decode using reserved range.
+  //
+  PciSegmentAnd16 (LanRegBase + PCI_COMMAND_OFFSET, (UINT16) ~EFI_PCI_COMMAND_MEMORY_SPACE);
+  PciSegmentWrite32 (LanRegBase + R_GBE_CFG_MBARA, GbeBar);
+  PciSegmentOr16 (LanRegBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
+
+  //
+  // If MBARA offset 5800h [0] = 1b then proceed with the w/a
+  //
+  if (MmioRead32 (GbeBar + R_GBE_MEM_CSR_WUC) & B_GBE_MEM_CSR_WUC_APME) {
+    Status = GbeMdiAcquireMdio (GbeBar);
+    ASSERT_EFI_ERROR (Status);
+    if (!EFI_ERROR (Status)) {
+      GbeWolWorkaround (GbeBar);
+      GbeMdiReleaseMdio (GbeBar);
+    }
+  }
+
+  //
+  // Disable MMIO decode.
+  //
+  PciSegmentAnd16 (LanRegBase + PCI_COMMAND_OFFSET, (UINT16) ~EFI_PCI_COMMAND_MEMORY_SPACE);
+  PciSegmentWrite32 (LanRegBase + R_GBE_CFG_MBARA, 0);
+}
+
+/**
+  Enable platform wake from LAN when in DeepSx if platform supports it.
+  Called upon Sx entry.
+**/
+VOID
+GbeConfigureDeepSxWake (
+  VOID
+  )
+{
+  if (PmcIsLanDeepSxWakeEnabled ()) {
+    IoOr32 ((UINTN) (mAcpiBaseAddr + R_ACPI_IO_GPE0_EN_127_96), (UINT32) B_ACPI_IO_GPE0_EN_127_96_LAN_WAKE);
+  }
+}
+
+/**
+  GbE Sx entry handler
+**/
+VOID
+PchLanSxCallback (
+  VOID
+  )
+{
+  if (IsGbeEnabled ()) {
+    GbeSxWorkaround ();
+    GbeConfigureDeepSxWake ();
+
+  }
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchBiosWriteProtect.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchBiosWriteProtect.c
new file mode 100644
index 0000000000..f435af434a
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchBiosWriteProtect.c
@@ -0,0 +1,137 @@
+/** @file
+  PCH BIOS Write Protect Driver.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "PchInitSmm.h"
+#include <Register/PchRegs.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/SpiRegs.h>
+#include <Library/SpiAccessPrivateLib.h>
+#include <Library/PchPciBdfLib.h>
+
+//
+// Global variables
+//
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_TCO_SMI_DISPATCH_PROTOCOL     *mPchTcoSmiDispatchProtocol;
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_ESPI_SMI_DISPATCH_PROTOCOL    *mEspiSmmDispatchProtocol;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT64                            mLpcRegBase;
+
+/**
+  This hardware SMI handler will be run every time the BIOS Write Enable bit is set.
+
+  @param[in] DispatchHandle       Not used
+**/
+VOID
+EFIAPI
+PchSpiBiosWpCallback (
+  IN  EFI_HANDLE                              DispatchHandle
+  )
+{
+  SpiClearBiosWriteProtectDisable ();
+}
+
+/**
+  This hardware SMI handler will be run every time the BIOS Write Enable bit is set.
+
+  @param[in] DispatchHandle       Not used
+
+**/
+VOID
+EFIAPI
+PchLpcBiosWpCallback (
+  IN  EFI_HANDLE                              DispatchHandle
+  )
+{
+  //
+  // Disable BIOSWE bit to protect BIOS
+  //
+  PciSegmentAnd8 ((UINTN) (mLpcRegBase + R_LPC_CFG_BC), (UINT8) ~B_LPC_CFG_BC_WPD);
+}
+
+/**
+  Entry point for Pch Bios Write Protect driver.
+
+  @param[in] ImageHandle          Image handle of this driver.
+  @param[in] SystemTable          Global system service table.
+
+  @retval EFI_SUCCESS             Initialization complete.
+**/
+EFI_STATUS
+EFIAPI
+InstallPchBiosWriteProtect (
+  IN EFI_HANDLE            ImageHandle,
+  IN EFI_SYSTEM_TABLE      *SystemTable
+  )
+{
+  EFI_STATUS              Status;
+  EFI_HANDLE              Handle;
+
+  DEBUG ((DEBUG_INFO, "InstallPchBiosWriteProtect()\n"));
+
+  if (mPchConfigHob->LockDown.BiosLock != TRUE) {
+    return EFI_SUCCESS;
+  }
+
+  mLpcRegBase = LpcPciCfgBase ();
+
+  DEBUG ((DEBUG_INFO, "Installing BIOS Write Protect SMI handler\n"));
+  //
+  // Get the PCH TCO SMM dispatch protocol
+  //
+  mPchTcoSmiDispatchProtocol = NULL;
+  Status = gSmst->SmmLocateProtocol (&gPchTcoSmiDispatchProtocolGuid, NULL, (VOID **) &mPchTcoSmiDispatchProtocol);
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Always register an SPI BiosWp callback function to handle TCO BIOSWR SMI
+  // NOTE: No matter the BIOS resides behind SPI or not, it needs to handle the SPI BIOS WP SMI
+  //       to avoid SMI deadloop on SPI WPD write.
+  //
+  Handle = NULL;
+  Status = mPchTcoSmiDispatchProtocol->SpiBiosWpRegister (
+                                         mPchTcoSmiDispatchProtocol,
+                                         PchSpiBiosWpCallback,
+                                         &Handle
+                                         );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Always register an LPC/eSPI BiosWp callback function to handle TCO BIOSWR SMI
+  // NOTE: No matter the BIOS resides behind LPC/eSPI or not, it needs to handle the BIOS WP SMI
+  //       to avoid SMI deadloop on LPC/eSPI WPD write.
+  //
+  if (IsEspiEnabled ()) {
+    //
+    // Get the PCH ESPI SMM dispatch protocol
+    //
+    mEspiSmmDispatchProtocol = NULL;
+    Status = gSmst->SmmLocateProtocol (&gPchEspiSmiDispatchProtocolGuid, NULL, (VOID **) &mEspiSmmDispatchProtocol);
+    ASSERT_EFI_ERROR (Status);
+
+    //
+    // Register an ESpiBiosWp callback function to handle BIOSWR SMI
+    //
+    Handle = NULL;
+    Status = mEspiSmmDispatchProtocol->BiosWrProtectRegister (
+                                         mEspiSmmDispatchProtocol,
+                                         PchLpcBiosWpCallback,
+                                         &Handle
+                                         );
+    ASSERT_EFI_ERROR (Status);
+  } else {
+    //
+    // Register an LPC BiosWp callback function to handle TCO BIOSWR SMI
+    //
+    Handle = NULL;
+    Status = mPchTcoSmiDispatchProtocol->LpcBiosWpRegister (
+                                           mPchTcoSmiDispatchProtocol,
+                                           PchLpcBiosWpCallback,
+                                           &Handle
+                                           );
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchHdaSxSmm.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchHdaSxSmm.c
new file mode 100644
index 0000000000..f3d11ab204
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchHdaSxSmm.c
@@ -0,0 +1,33 @@
+/** @file
+  PCH HD Audio Sx handler implementation.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchInitSmm.h"
+#include <Register/PchRegs.h>
+#include <Register/HdaRegs.h>
+#include <Library/PchPciBdfLib.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT64  mHdaPciBase;
+GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN mHdaCodecSxWakeCapability = FALSE;
+
+/**
+  Updates Codec Sx Wake Capability setting: disabled/enabled
+**/
+VOID
+UpdateHdaCodecSxWakeCapabilitySetting (
+  VOID
+  )
+{
+  mHdaPciBase = HdaPciCfgBase ();
+
+  if ((mPchConfigHob->HdAudio.CodecSxWakeCapability == FALSE) ||
+      (PciSegmentRead16 (mHdaPciBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF)) {
+    mHdaCodecSxWakeCapability = FALSE;
+  } else {
+    mHdaCodecSxWakeCapability = TRUE;
+  }
+}
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.c
new file mode 100644
index 0000000000..9c2475e3a1
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.c
@@ -0,0 +1,285 @@
+/** @file
+  PCH Init Smm module for PCH specific SMI handlers.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "PchInitSmm.h"
+#include <Register/PchRegs.h>
+#include <Register/UsbRegs.h>
+#include <Register/SmbusRegs.h>
+#include <Library/PchPciBdfLib.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL        *mPchIoTrap;
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_SMM_SX_DISPATCH2_PROTOCOL             *mSxDispatch;
+
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_NVS_AREA                              *mPchNvsArea;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16                                    mAcpiBaseAddr;
+
+GLOBAL_REMOVE_IF_UNREFERENCED FIVR_EXT_RAIL_CONFIG                      mFivrExtVnnRailSxConfig;
+
+//
+// NOTE: The module variables of policy here are only valid in post time, but not runtime time.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_CONFIG_HOB                            *mPchConfigHob;
+
+//
+// The reserved MMIO range to be used in Sx handler
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PHYSICAL_ADDRESS                      mResvMmioBaseAddr;
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN                                     mResvMmioSize;
+
+/**
+  SMBUS Sx entry SMI handler.
+**/
+VOID
+SmbusSxCallback (
+  VOID
+  )
+{
+  UINT64                      SmbusRegBase;
+  UINT16                      SmbusIoBase;
+
+  SmbusRegBase = SmbusPciCfgBase ();
+
+  if (PciSegmentRead32 (SmbusRegBase) == 0xFFFFFFFF) {
+    return;
+  }
+
+  SmbusIoBase = PciSegmentRead16 (SmbusRegBase + R_SMBUS_CFG_BASE) & B_SMBUS_CFG_BASE_BAR;
+  if (SmbusIoBase == 0) {
+    return;
+  }
+
+  PciSegmentOr8 (SmbusRegBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_IO_SPACE);
+  //
+  // Clear SMBUS status and SMB_WAK_STS of GPE0
+  //
+  IoWrite8 (SmbusIoBase + R_SMBUS_IO_HSTS, B_SMBUS_IO_SMBALERT_STS);
+  IoWrite32 (mAcpiBaseAddr + R_ACPI_IO_GPE0_STS_127_96, B_ACPI_IO_GPE0_STS_127_96_SMB_WAK);
+}
+
+/*
+  PCH xHCI Sx entry SMI handler
+*/
+VOID
+PchXhciSxCallback (
+  VOID
+  )
+{
+  UINTN      XhciPciBase;
+
+  XhciPciBase = PchXhciPciCfgBase ();
+
+  //
+  // Safety check for xHCI existense
+  //
+  if (PciSegmentRead32 (XhciPciBase) == 0xFFFFFFFF) {
+    return;
+  }
+
+  //
+  // If xHCI is in D0 that means OS didn't put it to D3 during Sx entry i.e. USB kernel debug is enabled.
+  // Unless it is put manually to D3, USB wake functionality will not work.
+  //
+  if ((PciSegmentRead8 (XhciPciBase + R_XHCI_CFG_PWR_CNTL_STS) & V_XHCI_CFG_PWR_CNTL_STS_PWR_STS_D3) == 0) {
+    //
+    // Put device to D3 to enable wake functionality for USB devices
+    //
+    PciSegmentOr8 (XhciPciBase + R_XHCI_CFG_PWR_CNTL_STS, (UINT8)(B_XHCI_CFG_PWR_CNTL_STS_PWR_STS));
+  }
+}
+
+/**
+  Cache PCH FIVR policy.
+**/
+VOID
+UpdatePchFivrSettings (
+  VOID
+  )
+{
+  CopyMem (
+    &mFivrExtVnnRailSxConfig,
+    &mPchConfigHob->Fivr.ExtVnnRailSx,
+    sizeof (mFivrExtVnnRailSxConfig)
+    );
+}
+
+/**
+  PCH Sx entry SMI handler.
+
+  @param[in]     Handle          Handle of the callback
+  @param[in]     Context         The dispatch context
+  @param[in,out] CommBuffer      A pointer to a collection of data in memory that will
+                                 be conveyed from a non-SMM environment into an SMM environment.
+  @param[in,out] CommBufferSize  The size of the CommBuffer.
+
+  @retval EFI_SUCCESS
+**/
+EFI_STATUS
+EFIAPI
+PchSxHandler (
+  IN  EFI_HANDLE                   Handle,
+  IN CONST VOID                    *Context OPTIONAL,
+  IN OUT VOID                      *CommBuffer OPTIONAL,
+  IN OUT UINTN                     *CommBufferSize OPTIONAL
+  )
+{
+  PchLanSxCallback ();
+  PchXhciSxCallback ();
+
+  SmbusSxCallback ();
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Initialize PCH Sx entry SMI handler.
+
+  @param[in] ImageHandle - Handle for the image of this driver
+**/
+VOID
+InitializeSxHandler (
+  IN EFI_HANDLE        ImageHandle
+  )
+{
+  EFI_SMM_SX_REGISTER_CONTEXT               SxDispatchContext;
+  EFI_HANDLE                                SxDispatchHandle;
+  EFI_SLEEP_TYPE                            SxType;
+  EFI_STATUS                                Status;
+
+  DEBUG ((DEBUG_INFO, "InitializeSxHandler() Start\n"));
+
+  //
+  // Register the callback for S3/S4/S5 entry
+  //
+  SxDispatchContext.Phase = SxEntry;
+  for (SxType = SxS3; SxType <= SxS5; SxType++) {
+    SxDispatchContext.Type  = SxType;
+    Status = mSxDispatch->Register (
+                            mSxDispatch,
+                            PchSxHandler,
+                            &SxDispatchContext,
+                            &SxDispatchHandle
+                            );
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  DEBUG ((DEBUG_INFO, "InitializeSxHandler() End\n"));
+}
+
+/**
+  Allocates reserved MMIO for Sx SMI handler use.
+**/
+VOID
+AllocateReservedMmio (
+  VOID
+  )
+{
+  mResvMmioBaseAddr = PcdGet32 (PcdSiliconInitTempMemBaseAddr);
+  mResvMmioSize     = PcdGet32 (PcdSiliconInitTempMemSize);
+  DEBUG ((DEBUG_INFO, "mResvMmioBaseAddr %x, mResvMmioSize %x\n", mResvMmioBaseAddr, mResvMmioSize));
+}
+
+/**
+  Initializes the PCH SMM handler for for PCIE hot plug support
+  <b>PchInit SMM Module Entry Point</b>\n
+  - <b>Introduction</b>\n
+      The PchInitSmm module is a SMM driver that initializes the Intel Platform Controller Hub
+      SMM requirements and services. It consumes the PCH_POLICY_HOB and SI_POLICY_HOB for expected
+      configurations per policy.
+
+  - <b>Details</b>\n
+    This module provides SMI handlers to services PCIE HotPlug SMI, LinkActive SMI, and LinkEq SMI.
+    And also provides port 0x61 emulation support, registers BIOS WP handler to process BIOSWP status,
+    and registers SPI Async SMI handler to handler SPI Async SMI.
+    This module also registers Sx SMI callback function to detail with GPIO Sx Isolation and LAN requirement.
+
+  - @pre
+    - PCH PCR base address configured
+    - EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+      - This is to ensure that PCI MMIO and IO resource has been prepared and available for this driver to allocate.
+    - EFI_SMM_BASE2_PROTOCOL
+    - EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL
+    - EFI_SMM_SX_DISPATCH2_PROTOCOL
+    - EFI_SMM_CPU_PROTOCOL
+    - @link _PCH_SMM_IO_TRAP_CONTROL_PROTOCOL PCH_SMM_IO_TRAP_CONTROL_PROTOCOL @endlink
+    - @link _PCH_SMI_DISPATCH_PROTOCOL PCH_SMI_DISPATCH_PROTOCOL @endlink
+    - @link _PCH_PCIE_SMI_DISPATCH_PROTOCOL PCH_PCIE_SMI_DISPATCH_PROTOCOL @endlink
+    - @link _PCH_TCO_SMI_DISPATCH_PROTOCOL PCH_TCO_SMI_DISPATCH_PROTOCOL @endlink
+    - @link _PCH_ESPI_SMI_DISPATCH_PROTOCOL PCH_ESPI_SMI_DISPATCH_PROTOCOL @endlink
+
+  - <b>References</b>\n
+    - @link _PCH_POLICY PCH_POLICY_HOB @endlink.
+    - @link _SI_POLICY_STRUCT SI_POLICY_HOB @endlink.
+
+  - <b>Integration Checklists</b>\n
+    - Verify prerequisites are met. Porting Recommendations.
+    - No modification of this module should be necessary
+    - Any modification of this module should follow the PCH BIOS Specification and EDS
+
+  @param[in] ImageHandle - Handle for the image of this driver
+  @param[in] SystemTable - Pointer to the EFI System Table
+
+  @retval EFI_SUCCESS    - PCH SMM handler was installed
+**/
+EFI_STATUS
+EFIAPI
+PchInitSmmEntryPoint (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS                                Status;
+  PCH_NVS_AREA_PROTOCOL                     *PchNvsAreaProtocol;
+  EFI_PEI_HOB_POINTERS                      HobPtr;
+
+  DEBUG ((DEBUG_INFO, "PchInitSmmEntryPoint()\n"));
+
+  Status = gSmst->SmmLocateProtocol (
+                    &gEfiSmmIoTrapDispatch2ProtocolGuid,
+                    NULL,
+                    (VOID **) &mPchIoTrap
+                    );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gSmst->SmmLocateProtocol (
+                    &gEfiSmmSxDispatch2ProtocolGuid,
+                    NULL,
+                    (VOID**) &mSxDispatch
+                    );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gBS->LocateProtocol (&gPchNvsAreaProtocolGuid, NULL, (VOID **) &PchNvsAreaProtocol);
+  ASSERT_EFI_ERROR (Status);
+  mPchNvsArea = PchNvsAreaProtocol->Area;
+
+  //
+  // Get PCH Data HOB.
+  //
+  HobPtr.Guid   = GetFirstGuidHob (&gPchConfigHobGuid);
+  ASSERT (HobPtr.Guid != NULL);
+  mPchConfigHob = (PCH_CONFIG_HOB *) GET_GUID_HOB_DATA (HobPtr.Guid);
+
+  mAcpiBaseAddr = PmcGetAcpiBase ();
+
+  AllocateReservedMmio ();
+
+  InitializeSxHandler (ImageHandle);
+
+  Status = InitializePchPcieSmm (ImageHandle, SystemTable);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = InstallPchBiosWriteProtect (ImageHandle, SystemTable);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = InstallPchSpiAsyncSmiHandler ();
+  ASSERT_EFI_ERROR (Status);
+
+  UpdateHdaCodecSxWakeCapabilitySetting ();
+
+  UpdatePchFivrSettings ();
+
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.h
new file mode 100644
index 0000000000..c2a09acd11
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.h
@@ -0,0 +1,254 @@
+/** @file
+  Header file for PCH Init SMM Handler
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_INIT_SMM_H_
+#define _PCH_INIT_SMM_H_
+
+#include <PiDxe.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Protocol/SmmSxDispatch2.h>
+#include <Protocol/SmmIoTrapDispatch2.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/HobLib.h>
+#include <Protocol/SmmCpu.h>
+#include <Library/TimerLib.h>
+
+#include <IndustryStandard/Pci30.h>
+#include <Library/PmcLib.h>
+#include <Library/PchPcieRpLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/SataLib.h>
+#include <Library/GpioLib.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/EspiLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PciExpressHelpersLib.h>
+#include <Protocol/PchPcieSmiDispatch.h>
+#include <Protocol/PchTcoSmiDispatch.h>
+#include <Protocol/PchSmiDispatch.h>
+#include <Protocol/PchEspiSmiDispatch.h>
+#include <Protocol/PchSmmIoTrapControl.h>
+#include <Protocol/PchNvsArea.h>
+#include <Protocol/PcieIoTrap.h>
+#include <SiConfigHob.h>
+#include <PchConfigHob.h>
+#include <Library/PmcPrivateLib.h>
+
+extern EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL        *mPchIoTrap;
+extern EFI_SMM_SX_DISPATCH2_PROTOCOL             *mSxDispatch;
+
+extern PCH_NVS_AREA                              *mPchNvsArea;
+extern UINT16                                    mAcpiBaseAddr;
+
+extern EFI_PHYSICAL_ADDRESS                      mResvMmioBaseAddr;
+extern UINTN                                     mResvMmioSize;
+
+//
+// NOTE: The module variables of policy here are only valid in post time, but not runtime time.
+//
+extern PCH_CONFIG_HOB                            *mPchConfigHob;
+extern SI_CONFIG_HOB_DATA                        *mSiConfigHobData;
+
+/**
+  Register PCIE Hotplug SMI dispatch function to handle Hotplug enabling
+
+  @param[in] ImageHandle          The image handle of this module
+  @param[in] SystemTable          The EFI System Table
+
+  @retval EFI_SUCCESS             The function completes successfully
+**/
+EFI_STATUS
+EFIAPI
+InitializePchPcieSmm (
+  IN      EFI_HANDLE            ImageHandle,
+  IN      EFI_SYSTEM_TABLE      *SystemTable
+  );
+
+/**
+  Program Common Clock and ASPM of Downstream Devices
+
+  @param[in] PortIndex                  Pcie Root Port Number
+  @param[in] RpDevice                   Pcie Root Pci Device Number
+  @param[in] RpFunction                 Pcie Root Pci Function Number
+
+  @retval EFI_SUCCESS                   Root port complete successfully
+  @retval EFI_UNSUPPORTED               PMC has invalid vendor ID
+**/
+EFI_STATUS
+PchPcieSmi (
+  IN  UINT8                             PortIndex,
+  IN  UINT8                             RpDevice,
+  IN  UINT8                             RpFunction
+  );
+
+/**
+  PCIE Hotplug SMI call back function for each Root port
+
+  @param[in] DispatchHandle             Handle of this dispatch function
+  @param[in] RpContext                  Rootport context, which contains RootPort Index,
+                                        and RootPort PCI BDF.
+**/
+VOID
+EFIAPI
+PchPcieSmiRpHandlerFunction (
+  IN  EFI_HANDLE                        DispatchHandle,
+  IN  PCH_PCIE_SMI_RP_CONTEXT           *RpContext
+  );
+
+/**
+  PCIE Link Active State Change Hotplug SMI call back function for all Root ports
+
+  @param[in] DispatchHandle             Handle of this dispatch function
+  @param[in] RpContext                  Rootport context, which contains RootPort Index,
+                                        and RootPort PCI BDF.
+**/
+VOID
+EFIAPI
+PchPcieLinkActiveStateChange (
+  IN  EFI_HANDLE                        DispatchHandle,
+  IN  PCH_PCIE_SMI_RP_CONTEXT           *RpContext
+  );
+
+/**
+  PCIE Link Equalization Request SMI call back function for all Root ports
+
+  @param[in] DispatchHandle             Handle of this dispatch function
+  @param[in] RpContext                  Rootport context, which contains RootPort Index,
+                                        and RootPort PCI BDF.
+**/
+VOID
+EFIAPI
+PchPcieLinkEqHandlerFunction (
+  IN  EFI_HANDLE                        DispatchHandle,
+  IN  PCH_PCIE_SMI_RP_CONTEXT           *RpContext
+  );
+
+/**
+  An IoTrap callback to config PCIE power management settings
+
+  @param[in] DispatchHandle  - The handle of this callback, obtained when registering
+  @param[in] DispatchContext - Pointer to the EFI_SMM_IO_TRAP_DISPATCH_CALLBACK_CONTEXT
+
+**/
+VOID
+EFIAPI
+PchPcieIoTrapSmiCallback (
+  IN     EFI_HANDLE                     DispatchHandle,
+  IN     EFI_SMM_IO_TRAP_CONTEXT        *CallbackContext,
+  IN OUT VOID                           *CommBuffer,
+  IN OUT UINTN                          *CommBufferSize
+  );
+
+/**
+  Initializes the PCH SMM handler for PCH save and restore
+
+  @param[in] ImageHandle - Handle for the image of this driver
+  @param[in] SystemTable - Pointer to the EFI System Table
+
+  @retval EFI_SUCCESS    - PCH SMM handler was installed
+**/
+EFI_STATUS
+EFIAPI
+PchInitLateSmm (
+  IN      EFI_HANDLE            ImageHandle,
+  IN      EFI_SYSTEM_TABLE      *SystemTable
+  );
+
+/**
+  Initialize PCH Sx entry SMI handler.
+
+  @param[in] ImageHandle - Handle for the image of this driver
+**/
+VOID
+InitializeSxHandler (
+  IN EFI_HANDLE        ImageHandle
+  );
+
+/**
+  PCH Sx entry SMI handler.
+
+  @param[in]     Handle          Handle of the callback
+  @param[in]     Context         The dispatch context
+  @param[in,out] CommBuffer      A pointer to a collection of data in memory that will
+                                 be conveyed from a non-SMM environment into an SMM environment.
+  @param[in,out] CommBufferSize  The size of the CommBuffer.
+
+  @retval EFI_SUCCESS
+**/
+
+EFI_STATUS
+EFIAPI
+PchSxHandler (
+  IN  EFI_HANDLE                   Handle,
+  IN CONST VOID                    *Context OPTIONAL,
+  IN OUT VOID                      *CommBuffer OPTIONAL,
+  IN OUT UINTN                     *CommBufferSize OPTIONAL
+  );
+
+/**
+  GbE Sx entry handler
+**/
+VOID
+PchLanSxCallback (
+  VOID
+  );
+
+/**
+  Updates Codec Sx Wake Capability setting: disabled/enabled
+**/
+VOID
+UpdateHdaCodecSxWakeCapabilitySetting (
+  VOID
+  );
+
+/**
+  Register dispatch function to handle GPIO pads Sx isolation
+**/
+VOID
+InitializeGpioSxIsolationSmm (
+  VOID
+  );
+
+/**
+  Entry point for Pch Bios Write Protect driver.
+
+  @param[in] ImageHandle          Image handle of this driver.
+  @param[in] SystemTable          Global system service table.
+
+  @retval EFI_SUCCESS             Initialization complete.
+**/
+EFI_STATUS
+EFIAPI
+InstallPchBiosWriteProtect (
+  IN EFI_HANDLE            ImageHandle,
+  IN EFI_SYSTEM_TABLE      *SystemTable
+  );
+
+/**
+  This fuction install SPI ASYNC SMI handler.
+
+  @retval EFI_SUCCESS             Initialization complete.
+**/
+EFI_STATUS
+EFIAPI
+InstallPchSpiAsyncSmiHandler (
+  VOID
+  );
+
+
+
+
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf
new file mode 100644
index 0000000000..aaf36a7b2a
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf
@@ -0,0 +1,110 @@
+## @file
+# Component description file for PchInitSmm driver
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PchInitSmm
+FILE_GUID = D7B10D4E-67E6-4C74-83E9-F9AF0ACC33CC
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_SMM_DRIVER
+PI_SPECIFICATION_VERSION = 1.10
+ENTRY_POINT = PchInitSmmEntryPoint
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+
+[LibraryClasses]
+UefiBootServicesTableLib
+UefiDriverEntryPoint
+DxeServicesTableLib
+IoLib
+DebugLib
+BaseLib
+BaseMemoryLib
+S3BootScriptLib
+PciExpressHelpersLib
+SmmServicesTableLib
+PciSegmentLib
+HobLib
+GpioLib
+GpioPrivateLib
+ReportStatusCodeLib
+DevicePathLib
+PmcLib
+PchPcieRpLib
+PchInfoLib
+EspiLib
+TimerLib
+ConfigBlockLib
+PmcPrivateLib
+SataLib
+GbeLib
+GbeMdiLib
+SpiAccessPrivateLib
+PchPciBdfLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+gSiPkgTokenSpaceGuid.PcdSiPciExpressBaseAddress
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempPciBusMin
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempPciBusMax
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempMemBaseAddr
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempMemSize
+
+
+[Sources]
+PchInitSmm.c
+PchPcieSmm.c
+GbeSxSmm.c
+PchInitSmm.h
+PchBiosWriteProtect.c
+PchSpiAsync.c
+PchHdaSxSmm.c
+
+
+[Protocols]
+gEfiSmmIoTrapDispatch2ProtocolGuid ## CONSUMES
+gEfiSmmSxDispatch2ProtocolGuid ## CONSUMES
+gPchSmmIoTrapControlGuid ## CONSUMES
+gEfiSmmCpuProtocolGuid ## CONSUMES
+gPchNvsAreaProtocolGuid ## CONSUMES
+gPchPcieSmiDispatchProtocolGuid ## CONSUMES
+gPchTcoSmiDispatchProtocolGuid ## CONSUMES
+gPchSmiDispatchProtocolGuid ## CONSUMES
+gPchEspiSmiDispatchProtocolGuid ## CONSUMES
+gPchPcieIoTrapProtocolGuid ## PRODUCES
+gPchPolicyProtocolGuid ##CONSUMES
+
+
+[Guids]
+gSiConfigHobGuid             ## CONSUMES
+gPchConfigHobGuid            ## CONSUMES
+gPchDeviceTableHobGuid
+gPchPcieRpDxeConfigGuid         ## CONSUMES
+
+
+[Depex]
+gEfiSmmIoTrapDispatch2ProtocolGuid AND
+gEfiSmmSxDispatch2ProtocolGuid AND
+gPchSmmIoTrapControlGuid AND
+gPchPcieSmiDispatchProtocolGuid AND
+gPchTcoSmiDispatchProtocolGuid AND
+gEfiSmmCpuProtocolGuid AND
+gPchNvsAreaProtocolGuid AND
+gEfiPciHostBridgeResourceAllocationProtocolGuid AND # This is to ensure that PCI MMIO resource has been prepared and available for this driver to allocate.
+gEfiSmmBase2ProtocolGuid AND # This is for SmmServicesTableLib
+gPchPolicyProtocolGuid
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchPcieSmm.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchPcieSmm.c
new file mode 100644
index 0000000000..e885a342a7
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchPcieSmm.c
@@ -0,0 +1,451 @@
+/** @file
+  PCH Pcie SMM Driver Entry
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "PchInitSmm.h"
+#include <PcieRegs.h>
+#include <Register/PchRegs.h>
+#include <Register/PchPcieRpRegs.h>
+#include <Library/PcieHelperLib.h>
+#include <Library/PchPciBdfLib.h>
+#include <Protocol/PchPolicy.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_PCIE_DEVICE_OVERRIDE      *mDevAspmOverride;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32                        mNumOfDevAspmOverride;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8                         mPchBusNumber;
+//
+// @note:
+// These temp bus numbers cannot be used in runtime (hot-plug).
+// These can be used only during boot.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8                         mTempRootPortBusNumMin;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8                         mTempRootPortBusNumMax;
+
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_PCIE_ROOT_PORT_CONFIG     mPcieRootPortConfig[PCH_MAX_PCIE_ROOT_PORTS];
+
+GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN                       mPchPciePmTrapExecuted = FALSE;
+
+extern EFI_GUID gPchDeviceTableHobGuid;
+
+/**
+  Program Common Clock and ASPM of Downstream Devices
+
+  @param[in] PortIndex                  Pcie Root Port Number
+  @param[in] RpDevice                   Pcie Root Pci Device Number
+  @param[in] RpFunction                 Pcie Root Pci Function Number
+
+  @retval EFI_SUCCESS                   Root port complete successfully
+  @retval EFI_UNSUPPORTED               PMC has invalid vendor ID
+**/
+EFI_STATUS
+PchPcieSmi (
+  IN  UINT8                             PortIndex,
+  IN  UINT8                             RpDevice,
+  IN  UINT8                             RpFunction
+  )
+{
+  UINT8                 SecBus;
+  UINT8                 SubBus;
+  UINT64                RpBase;
+  UINT64                EpBase;
+  UINT8                 EpPcieCapPtr;
+  UINT8                 EpMaxSpeed;
+  BOOLEAN               DownstreamDevicePresent;
+  UINT32                Timeout;
+
+  RpBase   = PCI_SEGMENT_LIB_ADDRESS (
+               DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+               mPchBusNumber,
+               (UINT32) RpDevice,
+               (UINT32) RpFunction,
+               0
+               );
+
+  if (PciSegmentRead16 (RpBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+    return EFI_SUCCESS;
+  }
+  //
+  // Check presence detect state. Here the endpoint must be detected using PDS rather than
+  // the usual LinkActive check, because PDS changes immediately and LA takes a few milliseconds to stabilize
+  //
+  DownstreamDevicePresent = !!(PciSegmentRead16 (RpBase + R_PCH_PCIE_CFG_SLSTS) & B_PCIE_SLSTS_PDS);
+
+  if (DownstreamDevicePresent) {
+    ///
+    /// Make sure the link is active before trying to talk to device behind it
+    /// Wait up to 100ms, according to PCIE spec chapter 6.7.3.3
+    ///
+    Timeout = 100 * 1000;
+    while ((PciSegmentRead16 (RpBase + R_PCH_PCIE_CFG_LSTS) & B_PCIE_LSTS_LA) == 0 ) {
+      MicroSecondDelay (10);
+      Timeout-=10;
+      if (Timeout == 0) {
+        return EFI_NOT_FOUND;
+      }
+    }
+    SecBus  = PciSegmentRead8 (RpBase + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+    SubBus  = PciSegmentRead8 (RpBase + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
+    ASSERT (SecBus != 0 && SubBus != 0);
+    RootportDownstreamConfiguration (
+      DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+      DEFAULT_PCI_BUS_NUMBER_PCH,
+      RpDevice,
+      RpFunction,
+      mTempRootPortBusNumMin,
+      mTempRootPortBusNumMax,
+      EnumPchPcie
+      );
+    RootportDownstreamPmConfiguration (
+      DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+      DEFAULT_PCI_BUS_NUMBER_PCH,
+      RpDevice,
+      RpFunction,
+      mTempRootPortBusNumMin,
+      mTempRootPortBusNumMax,
+      &mPcieRootPortConfig[PortIndex].PcieRpCommonConfig,
+      mNumOfDevAspmOverride,
+      mDevAspmOverride
+    );
+    //
+    // Perform Equalization
+    //
+    EpBase = PCI_SEGMENT_LIB_ADDRESS (DEFAULT_PCI_SEGMENT_NUMBER_PCH, SecBus, 0, 0, 0);
+    EpPcieCapPtr = PcieFindCapId (DEFAULT_PCI_SEGMENT_NUMBER_PCH, SecBus, 0, 0, EFI_PCI_CAPABILITY_ID_PCIEXP);
+    EpMaxSpeed = PciSegmentRead8 (EpBase + EpPcieCapPtr + R_PCIE_LCAP_OFFSET) & B_PCIE_LCAP_MLS;
+    if (EpMaxSpeed >= 3) {
+      PciSegmentOr32 (RpBase + R_PCH_PCIE_CFG_EX_LCTL3, B_PCIE_EX_LCTL3_PE);
+      PciSegmentOr32 (RpBase + R_PCH_PCIE_CFG_LCTL, B_PCIE_LCTL_RL);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  PCIE Hotplug SMI call back function for each Root port
+
+  @param[in] DispatchHandle             Handle of this dispatch function
+  @param[in] RpContext                  Rootport context, which contains RootPort Index,
+                                        and RootPort PCI BDF.
+**/
+VOID
+EFIAPI
+PchPcieSmiRpHandlerFunction (
+  IN  EFI_HANDLE                        DispatchHandle,
+  IN  PCH_PCIE_SMI_RP_CONTEXT           *RpContext
+  )
+{
+  PchPcieSmi (RpContext->RpIndex, RpContext->DevNum, RpContext->FuncNum);
+}
+
+/**
+  PCIE Link Active State Change Hotplug SMI call back function for all Root ports
+
+  @param[in] DispatchHandle             Handle of this dispatch function
+  @param[in] RpContext                  Rootport context, which contains RootPort Index,
+                                        and RootPort PCI BDF.
+**/
+VOID
+EFIAPI
+PchPcieLinkActiveStateChange (
+  IN  EFI_HANDLE                        DispatchHandle,
+  IN  PCH_PCIE_SMI_RP_CONTEXT           *RpContext
+  )
+{
+  return;
+}
+
+/**
+  PCIE Link Equalization Request SMI call back function for all Root ports
+
+  @param[in] DispatchHandle             Handle of this dispatch function
+  @param[in] RpContext                  Rootport context, which contains RootPort Index,
+                                        and RootPort PCI BDF.
+**/
+VOID
+EFIAPI
+PchPcieLinkEqHandlerFunction (
+  IN  EFI_HANDLE                        DispatchHandle,
+  IN  PCH_PCIE_SMI_RP_CONTEXT           *RpContext
+  )
+{
+  ///
+  /// From PCI Express specification, the PCIe device can request for Link Equalization. When the
+  /// Link Equalization is requested by the device, an SMI will be generated  by PCIe RP when
+  /// enabled and the SMI subroutine would invoke the Software Preset/Coefficient Search
+  /// software to re-equalize the link.
+  ///
+
+  return;
+
+}
+
+/**
+  An IoTrap callback to config PCIE power management settings
+**/
+VOID
+PchPciePmIoTrapSmiCallback (
+  VOID
+  )
+{
+  UINT32                                    PortIndex;
+  UINT64                                    RpBase;
+  UINT8                                     MaxPciePortNum;
+
+  MaxPciePortNum                   = GetPchMaxPciePortNum ();
+
+  for (PortIndex = 0; PortIndex < MaxPciePortNum; PortIndex++) {
+    RpBase = PchPcieRpPciCfgBase (PortIndex);
+
+    if (PciSegmentRead16 (RpBase) != 0xFFFF) {
+      RootportDownstreamPmConfiguration (
+        DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+        DEFAULT_PCI_BUS_NUMBER_PCH,
+        PchPcieRpDevNumber (PortIndex),
+        PchPcieRpFuncNumber (PortIndex),
+        mTempRootPortBusNumMin,
+        mTempRootPortBusNumMax,
+        &mPcieRootPortConfig[PortIndex].PcieRpCommonConfig,
+        mNumOfDevAspmOverride,
+        mDevAspmOverride
+      );
+
+    }
+  }
+}
+
+/**
+  An IoTrap callback to config PCIE power management settings
+
+  @param[in] DispatchHandle  - The handle of this callback, obtained when registering
+  @param[in] DispatchContext - Pointer to the EFI_SMM_IO_TRAP_DISPATCH_CALLBACK_CONTEXT
+
+**/
+VOID
+EFIAPI
+PchPcieIoTrapSmiCallback (
+  IN  EFI_HANDLE                            DispatchHandle,
+  IN  EFI_SMM_IO_TRAP_CONTEXT                *CallbackContext,
+  IN OUT VOID                               *CommBuffer,
+  IN OUT UINTN                              *CommBufferSize
+  )
+{
+  if (CallbackContext->WriteData == PchPciePmTrap) {
+    if (mPchPciePmTrapExecuted == FALSE) {
+      PchPciePmIoTrapSmiCallback ();
+      mPchPciePmTrapExecuted = TRUE;
+    }
+  } else {
+    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+  }
+}
+
+/**
+  This function clear the Io trap executed flag before enter S3
+
+  @param[in] Handle    Handle of the callback
+  @param[in] Context   The dispatch context
+
+  @retval EFI_SUCCESS  PCH register saved
+**/
+EFI_STATUS
+EFIAPI
+PchPcieS3EntryCallBack (
+  IN  EFI_HANDLE                        Handle,
+  IN CONST VOID                    *Context OPTIONAL,
+  IN OUT VOID                      *CommBuffer OPTIONAL,
+  IN OUT UINTN                     *CommBufferSize OPTIONAL
+  )
+{
+  mPchPciePmTrapExecuted = FALSE;
+  return EFI_SUCCESS;
+}
+/**
+  Register PCIE Hotplug SMI dispatch function to handle Hotplug enabling
+
+  @param[in] ImageHandle          The image handle of this module
+  @param[in] SystemTable          The EFI System Table
+
+  @retval EFI_SUCCESS             The function completes successfully
+**/
+EFI_STATUS
+EFIAPI
+InitializePchPcieSmm (
+  IN      EFI_HANDLE            ImageHandle,
+  IN      EFI_SYSTEM_TABLE      *SystemTable
+  )
+{
+  EFI_STATUS                            Status;
+  UINT8                                 PortIndex;
+  UINT8                                 Data8;
+  UINT32                                Data32Or;
+  UINT32                                Data32And;
+  UINT64                                RpBase;
+  EFI_HANDLE                            PcieHandle;
+  PCH_PCIE_SMI_DISPATCH_PROTOCOL        *PchPcieSmiDispatchProtocol;
+  EFI_HANDLE                            PchIoTrapHandle;
+  EFI_SMM_IO_TRAP_REGISTER_CONTEXT      PchIoTrapContext;
+  EFI_SMM_SX_REGISTER_CONTEXT           SxDispatchContext;
+  PCH_PCIE_IOTRAP_PROTOCOL              *PchPcieIoTrapProtocol;
+  EFI_HANDLE                            SxDispatchHandle;
+  UINT8                                 MaxPciePortNum;
+  PCH_POLICY_PROTOCOL                   *PchPolicy;
+  PCIE_RP_DXE_CONFIG                    *PchPcieRpDxeConfig;
+  UINTN                                 PcieDeviceTableSize;
+  PCH_PCIE_DEVICE_OVERRIDE              *DevAspmOverride;
+  UINTN                                 Count;
+
+  DEBUG ((DEBUG_INFO, "InitializePchPcieSmm () Start\n"));
+
+  MaxPciePortNum    = GetPchMaxPciePortNum ();
+
+  //
+  // Locate Pch Pcie Smi Dispatch Protocol
+  //
+  Status = gSmst->SmmLocateProtocol (&gPchPcieSmiDispatchProtocolGuid, NULL, (VOID**) &PchPcieSmiDispatchProtocol);
+  ASSERT_EFI_ERROR (Status);
+
+  mPchBusNumber = DEFAULT_PCI_BUS_NUMBER_PCH;
+  mTempRootPortBusNumMin = PcdGet8 (PcdSiliconInitTempPciBusMin);
+  mTempRootPortBusNumMax = PcdGet8 (PcdSiliconInitTempPciBusMax);
+
+  ASSERT (sizeof mPcieRootPortConfig == sizeof mPchConfigHob->PcieRp.RootPort);
+  CopyMem (
+    mPcieRootPortConfig,
+    &(mPchConfigHob->PcieRp.RootPort),
+    sizeof (mPcieRootPortConfig)
+    );
+
+  DevAspmOverride                   = NULL;
+  mDevAspmOverride                  = NULL;
+  mNumOfDevAspmOverride             = 0;
+
+  Status = gBS->LocateProtocol (&gPchPolicyProtocolGuid, NULL, (VOID **) &PchPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetConfigBlock ((VOID*) PchPolicy, &gPchPcieRpDxeConfigGuid, (VOID*) &PchPcieRpDxeConfig);
+  ASSERT_EFI_ERROR (Status);
+
+  DevAspmOverride = PchPcieRpDxeConfig->PcieDeviceOverrideTablePtr;
+
+  Count = 0;
+  if (DevAspmOverride != NULL) {
+    for (Count = 0; DevAspmOverride[Count].DeviceId != 0; Count++) {}
+  }
+
+  if (Count !=0) {
+    PcieDeviceTableSize = Count * sizeof (PCH_PCIE_DEVICE_OVERRIDE);
+    Status = gSmst->SmmAllocatePool (
+                      EfiRuntimeServicesData,
+                      PcieDeviceTableSize,
+                      (VOID **) &mDevAspmOverride
+                      );
+    ASSERT_EFI_ERROR (Status);
+    CopyMem (mDevAspmOverride, DevAspmOverride, PcieDeviceTableSize);
+    mNumOfDevAspmOverride = (UINT32) Count;
+  }
+  //
+  // Throught all PCIE root port function and register the SMI Handler for enabled ports.
+  //
+  for (PortIndex = 0; PortIndex < MaxPciePortNum; PortIndex++) {
+    RpBase = PchPcieRpPciCfgBase (PortIndex);
+    //
+    // Skip the root port function which is not enabled
+    //
+    if (PciSegmentRead32 (RpBase) == 0xFFFFFFFF) {
+      continue;
+    }
+
+    //
+    // Register SMI Handlers for Hot Plug and Link Active State Change
+    //
+    Data8 = PciSegmentRead8 (RpBase + R_PCH_PCIE_CFG_SLCAP);
+    if (Data8 & B_PCIE_SLCAP_HPC) {
+      PcieHandle = NULL;
+      Status = PchPcieSmiDispatchProtocol->HotPlugRegister (
+                                             PchPcieSmiDispatchProtocol,
+                                             PchPcieSmiRpHandlerFunction,
+                                             PortIndex,
+                                             &PcieHandle
+                                             );
+      ASSERT_EFI_ERROR (Status);
+
+      Status = PchPcieSmiDispatchProtocol->LinkActiveRegister (
+                                             PchPcieSmiDispatchProtocol,
+                                             PchPcieLinkActiveStateChange,
+                                             PortIndex,
+                                             &PcieHandle
+                                             );
+      ASSERT_EFI_ERROR (Status);
+
+      Data32Or  = B_PCH_PCIE_CFG_MPC_HPME;
+      Data32And = (UINT32) ~B_PCH_PCIE_CFG_MPC_HPME;
+      PciSegmentOr32 (RpBase + R_PCH_PCIE_CFG_MPC, Data32Or);
+      S3BootScriptSaveMemReadWrite (
+        S3BootScriptWidthUint32,
+        PcdGet64 (PcdSiPciExpressBaseAddress) + RpBase + R_PCH_PCIE_CFG_MPC,
+        &Data32Or,  /// Data to be ORed
+        &Data32And  /// Data to be ANDed
+        );
+    }
+
+    //
+    // Register SMI Handler for Link Equalization Request from Gen 3 Devices.
+    //
+    Data8 = PciSegmentRead8 (RpBase + R_PCH_PCIE_CFG_LCAP);
+    if ((Data8 & B_PCIE_LCAP_MLS) == V_PCIE_LCAP_MLS_GEN3) {
+      Status = PchPcieSmiDispatchProtocol->LinkEqRegister (
+                                             PchPcieSmiDispatchProtocol,
+                                             PchPcieLinkEqHandlerFunction,
+                                             PortIndex,
+                                             &PcieHandle
+                                             );
+      ASSERT_EFI_ERROR (Status);
+    }
+  }
+
+  ASSERT_EFI_ERROR (Status);
+
+  PchIoTrapContext.Type     = WriteTrap;
+  PchIoTrapContext.Length   = 4;
+  PchIoTrapContext.Address  = 0;
+  Status = mPchIoTrap->Register (
+                         mPchIoTrap,
+                         (EFI_SMM_HANDLER_ENTRY_POINT2) PchPcieIoTrapSmiCallback,
+                         &PchIoTrapContext,
+                         &PchIoTrapHandle
+                         );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Install the PCH Pcie IoTrap protocol
+  //
+  (gBS->AllocatePool) (EfiBootServicesData, sizeof (PCH_PCIE_IOTRAP_PROTOCOL), (VOID **)&PchPcieIoTrapProtocol);
+  PchPcieIoTrapProtocol->PcieTrapAddress = PchIoTrapContext.Address;
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gPchPcieIoTrapProtocolGuid,
+                  PchPcieIoTrapProtocol,
+                  NULL
+                  );
+
+  //
+  // Register the callback for S3 entry
+  //
+  SxDispatchContext.Type  = SxS3;
+  SxDispatchContext.Phase = SxEntry;
+  Status = mSxDispatch->Register (
+                          mSxDispatch,
+                          PchPcieS3EntryCallBack,
+                          &SxDispatchContext,
+                          &SxDispatchHandle
+                          );
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "InitializePchPcieSmm, IoTrap @ %x () End\n", PchIoTrapContext.Address));
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchSpiAsync.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchSpiAsync.c
new file mode 100644
index 0000000000..bdae6fe918
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchInit/Smm/PchSpiAsync.c
@@ -0,0 +1,67 @@
+/** @file
+  PCH SPI Async SMI handler.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "PchInitSmm.h"
+
+///
+/// Global variables
+///
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_SMI_DISPATCH_PROTOCOL     *mPchSmiDispatchProtocol;
+
+/**
+  This hardware SMI handler will be run every time the flash write/earse happens.
+
+  @param[in] DispatchHandle       Not used
+
+**/
+VOID
+EFIAPI
+PchSpiAsyncCallback (
+  IN  EFI_HANDLE                              DispatchHandle
+  )
+{
+  //
+  // Dummy SMI handler
+  //
+}
+
+/**
+  This fuction install SPI ASYNC SMI handler.
+
+  @retval EFI_SUCCESS             Initialization complete.
+**/
+EFI_STATUS
+EFIAPI
+InstallPchSpiAsyncSmiHandler (
+  VOID
+  )
+{
+  EFI_STATUS              Status;
+  EFI_HANDLE              Handle;
+
+  DEBUG ((DEBUG_INFO, "InstallPchSpiAsyncSmiHandler()\n"));
+
+  ///
+  /// Get the PCH SMM dispatch protocol
+  ///
+  mPchSmiDispatchProtocol = NULL;
+  Status = gSmst->SmmLocateProtocol (&gPchSmiDispatchProtocolGuid, NULL, (VOID **) &mPchSmiDispatchProtocol);
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Register an SpiAsync callback function
+  ///
+  Handle = NULL;
+  Status = mPchSmiDispatchProtocol->SpiAsyncRegister (
+                                      mPchSmiDispatchProtocol,
+                                      PchSpiAsyncCallback,
+                                      &Handle
+                                      );
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.c
new file mode 100644
index 0000000000..54a1575f2c
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.c
@@ -0,0 +1,1284 @@
+/** @file
+  Main implementation source file for the Io Trap SMM driver
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "PchSmmHelpers.h"
+#include <Protocol/PchNvsArea.h>
+#include <Library/SmiHandlerProfileLib.h>
+#include <Register/PchPcrRegs.h>
+#include <Register/PchRegsPsth.h>
+#include <Register/PchDmiRegs.h>
+
+#define GENERIC_IOTRAP_SIZE 0x100
+
+//
+// Module global variables
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_HANDLE                      mDriverImageHandle;
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_HANDLE                      mIoTrapHandle;
+
+GLOBAL_REMOVE_IF_UNREFERENCED IO_TRAP_INSTANCE                mIoTrapData;
+GLOBAL_REMOVE_IF_UNREFERENCED IO_TRAP_RECORD                  *mIoTrapRecord;
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_NVS_AREA                    *mPchNvsArea;
+
+
+static CONST UINT16             mLengthTable[10] = { 1, 2, 3, 4, 8, 16, 32, 64, 128, 256 };
+
+/**
+  Helper function that encapsulates IoTrap register access.
+  IO trap related register updates must be made in 2 registers, IOTRAP and DMI source decode.
+
+  @param[in] TrapHandlerNum    trap number (0-3)
+  @param[in] Value             value to be written in both registers
+  @param[in] SaveToBootscript  if true, this register write will be saved to bootscript
+
+**/
+VOID
+SetIoTrapLowDword (
+  IN UINT8   TrapHandlerNum,
+  IN UINT32  Value,
+  IN BOOLEAN SaveToBootscript
+  )
+{
+  UINT32  BitMask;
+  UINT32  BitValue;
+  //
+  // To provide sequentially consistent programming model for IO trap
+  // all pending IO cycles must be flushed before enabling and before disabling a trap.
+  // Without this the trap may trigger due to IO cycle issued before the trap is enabled or a cycle issued before the trap is disabled might be missed.
+  // a. Issues a MemRd to PSTH IO Trap Enable bit -> This serves to flush all previous IO cycles.
+  // b. Then only issues a MemWr to PSTH IO Trap Enable == Value
+  // c. Issues another MemRd to PSTH IO Trap Enable bit -> This serves to push the MemWr to PSTH and confirmed that IO Trap is in fact enabled
+  //
+  PchPcrRead32 (PID_PSTH, R_PSTH_PCR_TRPREG0 + TrapHandlerNum * 8);
+  PchPcrWrite32 (PID_PSTH, R_PSTH_PCR_TRPREG0 + TrapHandlerNum * 8, Value);
+  PchPcrRead32 (PID_PSTH, R_PSTH_PCR_TRPREG0 + TrapHandlerNum * 8);
+
+  PchPcrWrite32 (PID_DMI, R_PCH_DMI_PCR_IOT1 + TrapHandlerNum * 8, Value);
+  //
+  // Read back DMI IOTRAP register to enforce ordering so DMI write is completed before any IO reads
+  // from other threads which may occur after this point (after SMI exit).
+  //
+  PchPcrRead32 (PID_DMI, R_PCH_DMI_PCR_IOT1 + TrapHandlerNum * 8);
+  if (SaveToBootscript) {
+    //
+    // Ignore the value check of PCH_PCR_BOOT_SCRIPT_READ
+    //
+    BitMask  = 0;
+    BitValue = 0;
+
+    PCH_PCR_BOOT_SCRIPT_READ (S3BootScriptWidthUint32, PID_PSTH, R_PSTH_PCR_TRPREG0 + TrapHandlerNum * 8, &BitMask, &BitValue);
+    PCH_PCR_BOOT_SCRIPT_WRITE (S3BootScriptWidthUint32, PID_PSTH, R_PSTH_PCR_TRPREG0 + TrapHandlerNum * 8, 1, &Value);
+    PCH_PCR_BOOT_SCRIPT_READ (S3BootScriptWidthUint32, PID_PSTH, R_PSTH_PCR_TRPREG0 + TrapHandlerNum * 8, &BitMask, &BitValue);
+    PCH_PCR_BOOT_SCRIPT_WRITE (S3BootScriptWidthUint32, PID_DMI, R_PCH_DMI_PCR_IOT1 + TrapHandlerNum * 8, 1, &Value);
+  }
+}
+
+/**
+  Helper function that encapsulates IoTrap register access.
+  IO trap related register updates must be made in 2 registers, IOTRAP and DMI source decode.
+
+  @param[in] TrapHandlerNum    trap number (0-3)
+  @param[in] Value             value to be written in both registers
+  @param[in] SaveToBootscript  if true, this register write will be saved to bootscript
+
+**/
+VOID
+SetIoTrapHighDword (
+  IN UINT8   TrapHandlerNum,
+  IN UINT32  Value,
+  IN BOOLEAN SaveToBootscript
+  )
+{
+  PchPcrWrite32 (PID_PSTH, R_PSTH_PCR_TRPREG0 + TrapHandlerNum * 8 + 4, Value);
+  PchPcrWrite32 (PID_DMI, R_PCH_DMI_PCR_IOT1 + TrapHandlerNum * 8 + 4, Value);
+  if (SaveToBootscript) {
+    PCH_PCR_BOOT_SCRIPT_WRITE (S3BootScriptWidthUint32, PID_PSTH, R_PSTH_PCR_TRPREG0 + TrapHandlerNum * 8 + 4, 1, &Value);
+    PCH_PCR_BOOT_SCRIPT_WRITE (S3BootScriptWidthUint32, PID_DMI, R_PCH_DMI_PCR_IOT1 + TrapHandlerNum * 8 + 4, 1, &Value);
+  }
+}
+
+/**
+  Clear pending IOTRAP status.
+  If IOTRAP status is pending and IOTRAP is disabled, then BIOS will not find a match SMI source
+  and will not dispatch any SMI handler for it. The pending status will lead to SMI storm.
+  This prevents that IOTRAP gets triggered by pending IO cycles even after it's disabled.
+
+  @param[in] TrapHandlerNum    trap number (0-3)
+
+**/
+VOID
+ClearPendingIoTrapStatus (
+  IN UINT8   TrapHandlerNum
+  )
+{
+  PchPcrWrite32 (PID_PSTH, R_PSTH_PCR_TRPST, (UINT32)(1 << TrapHandlerNum));
+}
+
+/**
+  IO resources allocated to IO traps need to be reported to OS so that they don't get reused.
+  This function makes IO trap allocation data available to ACPI
+
+  @param[in] TrapHandlerNum  trap number (0-3)
+  @param[in] BaseAddress     address of allocated IO resource
+  @param[in] Track           TRUE = resource allocated, FALSE = resource freed
+
+**/
+VOID
+UpdateIoTrapAcpiResources (
+  IN UINT8                TrapHandlerNum,
+  IN EFI_PHYSICAL_ADDRESS BaseAddress,
+  IN BOOLEAN              Track
+  )
+{
+
+  if (Track == TRUE) {
+    mPchNvsArea->IoTrapAddress[TrapHandlerNum] = (UINT16) BaseAddress;
+    mPchNvsArea->IoTrapStatus[TrapHandlerNum] = 1;
+  } else {
+    mPchNvsArea->IoTrapStatus[TrapHandlerNum] = 0;
+  }
+}
+
+/**
+  Get address from IOTRAP low dword.
+
+  @param[in] IoTrapRegLowDword    IOTRAP register low dword
+
+  @retval                         Address of IOTRAP setting.
+**/
+STATIC
+UINT16
+AddressFromLowDword (
+  UINT32  IoTrapRegLowDword
+  )
+{
+  return (UINT16) (IoTrapRegLowDword & B_PSTH_PCR_TRPREG_AD);
+}
+
+/**
+  Get length from IOTRAP low dword.
+
+  @param[in] IoTrapRegLowDword    IOTRAP register low dword
+
+  @retval                         Length of IOTRAP setting.
+**/
+STATIC
+UINT16
+LengthFromLowDword (
+  UINT32  IoTrapRegLowDword
+  )
+{
+  return (UINT16) (((IoTrapRegLowDword >> 16) & 0xFC) + 4);
+}
+
+/**
+  Get ByteEnable from IOTRAP high dword.
+
+  @param[in] IoTrapRegHighDword   IOTRAP register high dword
+
+  @retval                         ByteEnable of IOTRAP setting.
+**/
+STATIC
+UINT8
+ByteEnableFromHighDword (
+  UINT32  IoTrapRegHighDword
+  )
+{
+  return (UINT8) (IoTrapRegHighDword & 0x0F);
+}
+
+/**
+  Get ByteEnableMask from IOTRAP high dword.
+
+  @param[in] IoTrapRegHighDword   IOTRAP register high dword
+
+  @retval                         ByteEnableMask of IOTRAP setting.
+**/
+STATIC
+UINT8
+ByteEnableMaskFromHighDword (
+  UINT32  IoTrapRegHighDword
+  )
+{
+  return (UINT8) ((IoTrapRegHighDword & 0xF0) >> 4);
+}
+
+/**
+  Check the IoTrap register matches the IOTRAP EX content.
+
+  @param[in] IoTrapRecord         IOTRAP registration record structure
+  @param[in] IoTrapRegLowDword    IOTRAP register low dword
+  @param[in] IoTrapRegHighDword   IOTRAP register high dword
+
+  @retval    TRUE                 Content matched
+             FALSE                Content mismatched
+**/
+STATIC
+BOOLEAN
+IsIoTrapExContentMatched (
+  IO_TRAP_RECORD  *IoTrapRecord,
+  UINT32          IoTrapRegLowDword,
+  UINT32          IoTrapRegHighDword
+  )
+{
+  if ((IoTrapRecord->Context.Address == AddressFromLowDword (IoTrapRegLowDword))          &&
+      (IoTrapRecord->Context.Length == LengthFromLowDword (IoTrapRegLowDword))            &&
+      (IoTrapRecord->Context.ByteEnable == ByteEnableFromHighDword (IoTrapRegHighDword))  &&
+      (IoTrapRecord->Context.ByteEnableMask == ByteEnableMaskFromHighDword (IoTrapRegHighDword)))
+  {
+    return TRUE;
+  }
+  return FALSE;
+}
+
+
+/**
+  The helper function for IoTrap callback dispacther
+
+  @param[in] TrapHandlerNum  trap number (0-3)
+**/
+VOID
+IoTrapDispatcherHelper (
+  UINTN                                     TrapHandlerNum
+  )
+{
+  IO_TRAP_RECORD                            *RecordInDb;
+  LIST_ENTRY                                *LinkInDb;
+  EFI_SMM_IO_TRAP_REGISTER_CONTEXT          CurrentIoTrapRegisterData;
+  EFI_SMM_IO_TRAP_CONTEXT                   CurrentIoTrapContextData;
+  UINT16                                    BaseAddress;
+  UINT16                                    StartAddress;
+  UINT16                                    EndAddress;
+  UINT32                                    Data32;
+  UINT8                                     ActiveHighByteEnable;
+  BOOLEAN                                   ReadCycle;
+  UINT32                                    WriteData;
+
+  if (!IsListEmpty (&(mIoTrapData.Entry[TrapHandlerNum].CallbackDataBase))) {
+    Data32 = PchPcrRead32 (PID_PSTH, R_PSTH_PCR_TRPC);
+    WriteData = PchPcrRead32 (PID_PSTH, R_PSTH_PCR_TRPD);
+
+    BaseAddress           = (UINT16) (Data32 & B_PSTH_PCR_TRPC_IOA);
+    ActiveHighByteEnable  = (UINT8)((Data32 & B_PSTH_PCR_TRPC_AHBE) >> 16);
+    ReadCycle             = (BOOLEAN) ((Data32 & B_PSTH_PCR_TRPC_RW) == B_PSTH_PCR_TRPC_RW);
+    //
+    // StartAddress and EndAddress will be equal if it's byte access
+    //
+    EndAddress    = (UINT16) (HighBitSet32 ((UINT32) (ActiveHighByteEnable))) + BaseAddress;
+    StartAddress  = (UINT16) (LowBitSet32 ((UINT32) (ActiveHighByteEnable))) + BaseAddress;
+
+    CurrentIoTrapRegisterData.Type = (EFI_SMM_IO_TRAP_DISPATCH_TYPE)ReadCycle;
+    CurrentIoTrapContextData.WriteData = WriteData;
+
+    LinkInDb = GetFirstNode (&(mIoTrapData.Entry[TrapHandlerNum].CallbackDataBase));
+
+    while (!IsNull (&(mIoTrapData.Entry[TrapHandlerNum].CallbackDataBase), LinkInDb)) {
+      RecordInDb = IO_TRAP_RECORD_FROM_LINK (LinkInDb);
+
+      //
+      // If MergeDisable is TRUE, no need to check the address range, dispatch the callback function directly.
+      //
+      if (mIoTrapData.Entry[TrapHandlerNum].MergeDisable) {
+        if (RecordInDb->IoTrapCallback != NULL) {
+          RecordInDb->IoTrapCallback (&RecordInDb->Link, &CurrentIoTrapContextData, NULL, NULL);
+        }
+        if (RecordInDb->IoTrapExCallback != NULL) {
+          RecordInDb->IoTrapExCallback (BaseAddress, ActiveHighByteEnable, !ReadCycle, WriteData);
+        }
+        //
+        // Expect only one callback available. So break immediately.
+        //
+        break;
+      //
+      // If MergeDisable is FALSE, check the address range and trap type.
+      //
+      } else {
+        if ((RecordInDb->Context.Address <= StartAddress) &&
+            (RecordInDb->Context.Address + RecordInDb->Context.Length > EndAddress)) {
+          if ((RecordInDb->Context.Type == IoTrapExTypeReadWrite) || (RecordInDb->Context.Type == (IO_TRAP_EX_DISPATCH_TYPE) CurrentIoTrapRegisterData.Type)) {
+            //
+            // Pass the IO trap context information
+            //
+            RecordInDb->IoTrapCallback (&RecordInDb->Link, &CurrentIoTrapContextData, NULL, NULL);
+          }
+          //
+          // Break if the address is match
+          //
+          break;
+        } else {
+          LinkInDb = GetNextNode (&(mIoTrapData.Entry[TrapHandlerNum].CallbackDataBase), &RecordInDb->Link);
+          if (IsNull (&(mIoTrapData.Entry[TrapHandlerNum].CallbackDataBase), LinkInDb)) {
+            //
+            // An IO access was trapped that does not have a handler registered.
+            // This indicates an error condition.
+            //
+            ASSERT (FALSE);
+          }
+        }
+      } // end of if else block
+    } // end of while loop
+  } // end of if else block
+}
+
+/**
+  IoTrap dispatcher for IoTrap register 0.
+
+  @param[in] DispatchHandle             Handle of dispatch function
+**/
+VOID
+EFIAPI
+IoTrapDispatcher0 (
+  IN  EFI_HANDLE                        DispatchHandle
+  )
+{
+  IoTrapDispatcherHelper (0);
+}
+
+/**
+  IoTrap dispatcher for IoTrap register 1.
+
+  @param[in] DispatchHandle             Handle of dispatch function
+**/
+VOID
+EFIAPI
+IoTrapDispatcher1 (
+  IN  EFI_HANDLE                        DispatchHandle
+  )
+{
+  IoTrapDispatcherHelper (1);
+}
+
+/**
+  IoTrap dispatcher for IoTrap register 2.
+
+  @param[in] DispatchHandle             Handle of dispatch function
+**/
+VOID
+EFIAPI
+IoTrapDispatcher2 (
+  IN  EFI_HANDLE                        DispatchHandle
+  )
+{
+  IoTrapDispatcherHelper (2);
+}
+
+/**
+  IoTrap dispatcher for IoTrap register 3.
+
+  @param[in] DispatchHandle             Handle of dispatch function
+**/
+VOID
+EFIAPI
+IoTrapDispatcher3 (
+  IN  EFI_HANDLE                        DispatchHandle
+  )
+{
+  IoTrapDispatcherHelper (3);
+}
+
+/**
+  IoTrap registratrion helper fucntion.
+
+  @param[in] DispatchHandle             Handle of dispatch function
+  @param[in] IoTrapDispatchFunction     Dispatch function of IoTrapDispatch2Protocol.
+                                        This could be NULL if it's not from IoTrapDispatch2Protocol.
+  @param[in] IoTrapExDispatchFunction   Dispatch function of IoTrapExDispatchProtocol.
+                                        This could be NULL if it's not from IoTrapExDispatchProtocol.
+  @param[in out] Address                The pointer of IO Address.
+                                        If the input Addres is 0, it will return the address assigned
+                                        by registration to this caller.
+  @param[in] Length                     Length of IO address range.
+  @param[in] Type                       Read/Write type of IO trap.
+  @param[in] ByteEnable                 Bitmap to enable trap for each byte of every dword alignment address.
+  @param[in] ByteEnableMask             ByteEnableMask bitwise to ignore the ByteEnable setting.
+
+  @retval    EFI_INVALID_PARAMETER      If Type is invalid,
+                                        If Length is invalid,
+                                        If Address is invalid,
+             EFI_ACCESS_DENIED          If the SmmReadyToLock event has been triggered,
+             EFI_OUT_OF_RESOURCES       If run out of IoTrap register resource,
+                                        If run out of SMM memory pool,
+             EFI_SUCCESS                IoTrap register successfully.
+**/
+EFI_STATUS
+IoTrapRegisterHelper (
+  OUT       EFI_HANDLE                             *DispatchHandle,
+  IN        EFI_SMM_HANDLER_ENTRY_POINT2           IoTrapDispatchFunction,
+  IN        IO_TRAP_EX_DISPATCH_CALLBACK           IoTrapExDispatchFunction,
+  IN OUT    UINT16                                 *Address,
+  IN        UINT16                                 Length,
+  IN        IO_TRAP_EX_DISPATCH_TYPE               Type,
+  IN        UINT8                                  ByteEnable,
+  IN        UINT8                                  ByteEnableMask
+  )
+{
+  EFI_STATUS            Status;
+  EFI_PHYSICAL_ADDRESS  BaseAddress;
+  UINT32                UsedLength;
+  UINT8                 TrapHandlerNum;
+  UINT32                IoTrapRegLowDword;
+  UINT32                IoTrapRegHighDword;
+  BOOLEAN               TempMergeDisable;
+
+  DEBUG ((DEBUG_INFO, "IoTrapRegisterHelper\n"));
+  DEBUG ((DEBUG_INFO, "Address:%x \n", *Address));
+  DEBUG ((DEBUG_INFO, "Length:%x \n", Length));
+  DEBUG ((DEBUG_INFO, "Type:%x \n", Type));
+  DEBUG ((DEBUG_INFO, "ByteEnable:%x \n", ByteEnable));
+  DEBUG ((DEBUG_INFO, "ByteEnableMask:%x \n", ByteEnableMask));
+
+  //
+  // Return error if the type is invalid
+  //
+  if (Type >= IoTrapExTypeMaximum) {
+    DEBUG ((DEBUG_ERROR, "The Dispatch Type %0X is invalid! \n", Type));
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Return error if the Length is invalid
+  //
+  if (Length < 1 || Length > GENERIC_IOTRAP_SIZE) {
+    DEBUG ((DEBUG_ERROR, "The Dispatch Length %0X is invalid! \n", Length));
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Return error if the address is invalid
+  // PCH supports non-aligned address but (Address % 4 + Length) must not be more than 4
+  //
+  if (((Length & (Length - 1)) != 0) && (Length != 3)) {
+    DEBUG ((DEBUG_ERROR, "The Dispatch Length is not power of 2 \n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (((Length >= 4) && (*Address & 0x3)) ||
+      ((Length < 4) && (((*Address & 0x3) + Length) > 4))) {
+    DEBUG ((DEBUG_ERROR, "PCH does not support Dispatch Address %0X and Length %0X combination \n", *Address, Length));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((Length >= 4) && ((*Address & (Length - 1)) != 0)) {
+    DEBUG ((DEBUG_ERROR, "Dispatch Address %0X is not aligned to the Length %0X \n", *Address, Length));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  if (*Address) {
+    TempMergeDisable = TRUE;
+  }else {
+    TempMergeDisable = FALSE;
+  }
+  //
+  // Loop through the first IO Trap handler, looking for the suitable handler
+  //
+  for (TrapHandlerNum = 0; TrapHandlerNum < IO_TRAP_HANDLER_NUM; TrapHandlerNum++) {
+    //
+    // Get information from Io Trap handler register
+    //
+    IoTrapRegLowDword = PchPcrRead32 (PID_PSTH, R_PSTH_PCR_TRPREG0 + TrapHandlerNum * 8);
+
+    //
+    // Check if the IO Trap handler is not used
+    //
+    if (AddressFromLowDword (IoTrapRegLowDword) == 0) {
+      //
+      //  Search available IO address and allocate it if the IO address is 0
+      //
+      BaseAddress = *Address;
+      if (BaseAddress == 0) {
+        //
+        // Allocate 256 byte range from GCD for common pool usage
+        //
+        if ((PcdGet8 (PcdEfiGcdAllocateType) == EfiGcdAllocateMaxAddressSearchBottomUp) || (PcdGet8 (PcdEfiGcdAllocateType) == EfiGcdAllocateMaxAddressSearchTopDown)) {
+          BaseAddress = 0xFFFF;
+        }
+        Status = gDS->AllocateIoSpace (
+                        PcdGet8 (PcdEfiGcdAllocateType),
+                        EfiGcdIoTypeIo,
+                        8,
+                        GENERIC_IOTRAP_SIZE,
+                        &BaseAddress,
+                        mDriverImageHandle,
+                        NULL
+                        );
+        if (EFI_ERROR (Status)) {
+          DEBUG ((DEBUG_ERROR, "Can't find any available IO address! \n"));
+          return EFI_OUT_OF_RESOURCES;
+        }
+
+        *Address   = (UINT16) BaseAddress;
+        UsedLength = GENERIC_IOTRAP_SIZE;
+        mIoTrapData.Entry[TrapHandlerNum].TrapUsedLength = Length;
+        mIoTrapData.Entry[TrapHandlerNum].ReservedAcpiIoResource = TRUE;
+        UpdateIoTrapAcpiResources (TrapHandlerNum, BaseAddress, TRUE);
+      } else {
+        BaseAddress &= B_PSTH_PCR_TRPREG_AD;
+        UsedLength = Length;
+      }
+
+      Status = PchInternalIoTrapSmiRegister (
+                 mIoTrapData.Entry[TrapHandlerNum].CallbackDispatcher,
+                 TrapHandlerNum,
+                 &mIoTrapHandle
+                 );
+
+      ASSERT_EFI_ERROR (Status);
+      mIoTrapData.Entry[TrapHandlerNum].IoTrapHandle = mIoTrapHandle;
+
+      //
+      // Fill in the Length, address and Enable the IO Trap SMI
+      //
+      IoTrapRegLowDword = (UINT32) (((UsedLength - 1) & ~(BIT1 + BIT0)) << 16) |
+        (UINT16) BaseAddress |
+        B_PSTH_PCR_TRPREG_TSE;
+
+      if (UsedLength < 4) {
+        //
+        // The 4 bits is the Byte Enable Mask bits to indicate which byte that are trapped.
+        // The input ByteEnable and ByteEnableMask are ignored in this case.
+        //
+        IoTrapRegHighDword  = (((1 << UsedLength) - 1) << ((*Address & 0x3) + (N_PSTH_PCR_TRPREG_BEM - 32))) |
+          (UINT32) (Type << N_PSTH_PCR_TRPREG_RWIO);
+      } else {
+        //
+        // Fill in the ByteEnable, ByteEnableMask, and Type of Io Trap register
+        //
+        IoTrapRegHighDword  = ((ByteEnableMask & 0xF) << (N_PSTH_PCR_TRPREG_BEM - 32)) |
+          ((ByteEnable & 0xF) << (N_PSTH_PCR_TRPREG_BE - 32)) |
+          (UINT32) (Type << N_PSTH_PCR_TRPREG_RWIO);
+      }
+      SetIoTrapHighDword (TrapHandlerNum, IoTrapRegHighDword, TRUE);
+      SetIoTrapLowDword (TrapHandlerNum, IoTrapRegLowDword, TRUE);
+      //
+      // Set MergeDisable flag of the registered IoTrap
+      //
+      mIoTrapData.Entry[TrapHandlerNum].MergeDisable = TempMergeDisable;
+    } else {
+      //
+      // Check next handler if MergeDisable is TRUE or the registered IoTrap if MergeDisable is TRUE
+      // If the Io Trap register is used by IoTrapEx protocol, then the MergeDisable will be FALSE.
+      //
+      if ((TempMergeDisable == TRUE) || (mIoTrapData.Entry[TrapHandlerNum].MergeDisable == TRUE)) {
+        continue;
+      }
+      //
+      // The IO Trap handler is used, calculate the Length
+      //
+      UsedLength  = LengthFromLowDword (IoTrapRegLowDword);
+      BaseAddress = AddressFromLowDword (IoTrapRegLowDword);
+      //
+      //  Assign an addfress from common pool if the caller's address is 0
+      //
+      if (*Address == 0) {
+        //
+        //  Check next handler if it's fully used
+        //
+        if (mIoTrapData.Entry[TrapHandlerNum].TrapUsedLength >= GENERIC_IOTRAP_SIZE) {
+          continue;
+        }
+        //
+        // Check next handler if it's not for a common pool
+        //
+        if (UsedLength < GENERIC_IOTRAP_SIZE) {
+          continue;
+        }
+        //
+        // Check next handler if the size is too big
+        //
+        if (Length >= (UINT16) GENERIC_IOTRAP_SIZE - mIoTrapData.Entry[TrapHandlerNum].TrapUsedLength) {
+          continue;
+        }
+        //
+        // For common pool, we don't need to change the BaseAddress and UsedLength
+        //
+        *Address = (UINT16) (BaseAddress + mIoTrapData.Entry[TrapHandlerNum].TrapUsedLength);
+        mIoTrapData.Entry[TrapHandlerNum].TrapUsedLength += Length;
+      }
+      //
+      // Only set RWM bit when we need both read and write cycles.
+      //
+      IoTrapRegHighDword = PchPcrRead32 (PID_PSTH, R_PSTH_PCR_TRPREG0 + TrapHandlerNum * 8 + 4);
+      if ((IoTrapRegHighDword & B_PSTH_PCR_TRPREG_RWM) == 0 &&
+          (UINT32) ((IoTrapRegHighDword & B_PSTH_PCR_TRPREG_RWIO) >> N_PSTH_PCR_TRPREG_RWIO) !=
+          (UINT32) Type) {
+        IoTrapRegHighDword = ((IoTrapRegHighDword | B_PSTH_PCR_TRPREG_RWM) & ~B_PSTH_PCR_TRPREG_RWIO);
+        SetIoTrapHighDword (TrapHandlerNum, IoTrapRegHighDword, TRUE);
+      }
+    }
+    break;
+  }
+
+  if (TrapHandlerNum >= IO_TRAP_HANDLER_NUM) {
+    DEBUG ((DEBUG_ERROR, "All IO Trap handler is used, no available IO Trap handler! \n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+  //
+  // Create database record and add to database
+  //
+  Status = gSmst->SmmAllocatePool (
+                    EfiRuntimeServicesData,
+                    sizeof (IO_TRAP_RECORD),
+                    (VOID **) &mIoTrapRecord
+                    );
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed to allocate memory for mIoTrapRecord! \n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+  //
+  // Gather information about the registration request
+  //
+  mIoTrapRecord->Signature               = IO_TRAP_RECORD_SIGNATURE;
+  mIoTrapRecord->Context.Address         = *Address;
+  mIoTrapRecord->Context.Length          = Length;
+  mIoTrapRecord->Context.Type            = Type;
+  mIoTrapRecord->Context.ByteEnable      = ByteEnable;
+  mIoTrapRecord->Context.ByteEnableMask  = ByteEnableMask;
+  mIoTrapRecord->IoTrapCallback          = IoTrapDispatchFunction;
+  mIoTrapRecord->IoTrapExCallback        = IoTrapExDispatchFunction;
+  mIoTrapRecord->IoTrapNumber            = TrapHandlerNum;
+
+  InsertTailList (&(mIoTrapData.Entry[TrapHandlerNum].CallbackDataBase), &mIoTrapRecord->Link);
+
+  //
+  // Child's handle will be the address linked list link in the record
+  //
+  *DispatchHandle = (EFI_HANDLE) (&mIoTrapRecord->Link);
+
+  DEBUG ((DEBUG_INFO, "Result Address:%x \n", *Address));
+  DEBUG ((DEBUG_INFO, "Result Length:%x \n", Length));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  IoTrap unregistratrion helper fucntion.
+
+  @param[in] DispatchHandle             Handle of dispatch function
+
+  @retval    EFI_INVALID_PARAMETER      If DispatchHandle is invalid,
+             EFI_ACCESS_DENIED          If the SmmReadyToLock event has been triggered,
+             EFI_SUCCESS                IoTrap unregister successfully.
+**/
+EFI_STATUS
+IoTrapUnRegisterHelper (
+  IN EFI_HANDLE                                  DispatchHandle
+  )
+{
+  EFI_STATUS            Status;
+  IO_TRAP_RECORD        *RecordToDelete;
+  UINT32                IoTrapRegLowDword;
+  EFI_PHYSICAL_ADDRESS  BaseAddress;
+  UINT32                UsedLength;
+  UINT8                 TrapHandlerNum;
+  UINT8                 LengthIndex;
+  BOOLEAN               RequireToDisableIoTrapHandler;
+
+  if (DispatchHandle == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "UnRegister is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  RecordToDelete = IO_TRAP_RECORD_FROM_LINK (DispatchHandle);
+  //
+  // Take the entry out of the linked list
+  //
+  if (RecordToDelete->Link.ForwardLink == (LIST_ENTRY *) EFI_BAD_POINTER) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  RequireToDisableIoTrapHandler = FALSE;
+  //
+  // Loop through the first IO Trap handler, looking for the suitable handler
+  //
+  TrapHandlerNum = RecordToDelete->IoTrapNumber;
+
+  if (mIoTrapData.Entry[TrapHandlerNum].MergeDisable) {
+    //
+    // Disable the IO Trap handler if it's the only child of the Trap handler
+    //
+    RequireToDisableIoTrapHandler = TRUE;
+  } else {
+    //
+    // Get information from Io Trap handler register
+    //
+    IoTrapRegLowDword = PchPcrRead32 (PID_PSTH, R_PSTH_PCR_TRPREG0 + TrapHandlerNum * 8);
+
+    //
+    // Check next Io Trap handler if the IO Trap handler is not used
+    //
+    if (AddressFromLowDword (IoTrapRegLowDword) != 0) {
+
+      UsedLength  = LengthFromLowDword (IoTrapRegLowDword);
+      BaseAddress = AddressFromLowDword (IoTrapRegLowDword);
+
+      //
+      // Check if it's the maximum address of the Io Trap handler
+      //
+      if ((UINTN)(BaseAddress + UsedLength) == (UINTN)(RecordToDelete->Context.Address + RecordToDelete->Context.Length)) {
+
+        if (BaseAddress == RecordToDelete->Context.Address) {
+          //
+          // Disable the IO Trap handler if it's the only child of the Trap handler
+          //
+          RequireToDisableIoTrapHandler = TRUE;
+        } else {
+          //
+          // Calculate the new IO Trap handler Length
+          //
+          UsedLength = UsedLength - RecordToDelete->Context.Length;
+          //
+          // Check the alignment is dword * power of 2 or not
+          //
+          for (LengthIndex = 0; LengthIndex < sizeof (mLengthTable) / sizeof (UINT16); LengthIndex++) {
+            if (UsedLength == mLengthTable[LengthIndex]) {
+              break;
+            }
+          }
+          //
+          // Do not decrease the length if the alignment is not dword * power of 2
+          //
+          if (LengthIndex < sizeof (mLengthTable) / sizeof (UINT16)) {
+            //
+            // Decrease the length to prevent the IO trap SMI
+            //
+            IoTrapRegLowDword = (UINT32) ((((UsedLength - 1) &~(BIT1 + BIT0)) << 16) | BaseAddress | B_PSTH_PCR_TRPREG_TSE);
+          }
+          SetIoTrapLowDword (TrapHandlerNum, IoTrapRegLowDword, TRUE);
+        }
+      }
+    }
+  }
+
+  if (RequireToDisableIoTrapHandler) {
+    mIoTrapHandle = mIoTrapData.Entry[TrapHandlerNum].IoTrapHandle;
+    Status        = PchInternalIoTrapSmiUnRegister (mIoTrapHandle);
+    ASSERT_EFI_ERROR (Status);
+
+    SetIoTrapLowDword (TrapHandlerNum, 0, TRUE);
+    SetIoTrapHighDword (TrapHandlerNum, 0, TRUE);
+    //
+    // Also clear pending IOTRAP status.
+    //
+    ClearPendingIoTrapStatus (TrapHandlerNum);
+
+    mIoTrapData.Entry[TrapHandlerNum].IoTrapHandle = 0;
+    mIoTrapData.Entry[TrapHandlerNum].MergeDisable = FALSE;
+    if (mIoTrapData.Entry[TrapHandlerNum].ReservedAcpiIoResource == TRUE) {
+      mIoTrapData.Entry[TrapHandlerNum].ReservedAcpiIoResource = FALSE;
+      UpdateIoTrapAcpiResources (TrapHandlerNum, 0, FALSE);
+    }
+  }
+
+  RemoveEntryList (&RecordToDelete->Link);
+  Status = gSmst->SmmFreePool (RecordToDelete);
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Register a new IO Trap SMI dispatch function with a parent SMM driver.
+  The caller will provide information about the IO trap characteristics via
+  the context.  This includes base address, length, read vs. r/w, etc.
+  This function will autoallocate IO base address from a common pool if the base address is 0,
+  and the RegisterContext Address field will be updated.
+  The service will not perform GCD allocation if the base address is non-zero.
+  In this case, the caller is responsible for the existence and allocation of the
+  specific IO range.
+  This function looks for the suitable handler and Register a new IoTrap handler
+  if the IO Trap handler is not used. It also enable the IO Trap Range to generate
+  SMI.
+
+  @param[in] This                 Pointer to the EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL instance.
+  @param[in] DispatchFunction     Pointer to dispatch function to be invoked for
+                                  this SMI source.
+  @param[in, out] RegisterContext Pointer to the dispatch function's context.
+                                  The caller fills this context in before calling
+                                  the register function to indicate to the register
+                                  function the IO trap SMI source for which the dispatch
+                                  function should be invoked.  This may not be NULL.
+                                  If the registration address is not 0, it's caller's responsibility
+                                  to reserve the IO resource in ACPI.
+  @param[out] DispatchHandle      Handle of dispatch function, for when interfacing
+                                  with the parent SMM driver, will be the address of linked
+                                  list link in the call back record.  This may not be NULL.
+
+  @retval EFI_SUCCESS             The dispatch function has been successfully
+                                  registered and the SMI source has been enabled.
+  @retval EFI_DEVICE_ERROR        The driver was unable to enable the SMI source.
+  @retval EFI_OUT_OF_RESOURCES    Insufficient resources are available
+  @retval EFI_INVALID_PARAMETER   Address requested is already in use.
+  @retval EFI_ACCESS_DENIED       Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+IoTrapRegister (
+  IN CONST  EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL     *This,
+  IN        EFI_SMM_HANDLER_ENTRY_POINT2           DispatchFunction,
+  IN OUT    EFI_SMM_IO_TRAP_REGISTER_CONTEXT       *RegisterContext,
+  OUT       EFI_HANDLE                             *DispatchHandle
+  )
+{
+  EFI_STATUS Status;
+
+  DEBUG ((DEBUG_INFO, "IoTrapRegister\n"));
+  Status = IoTrapRegisterHelper (
+             DispatchHandle,
+             DispatchFunction,
+             NULL,
+             &(RegisterContext->Address),
+             RegisterContext->Length,
+             (IO_TRAP_EX_DISPATCH_TYPE) RegisterContext->Type,
+             0x00,
+             0x0F);
+
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileRegisterHandler (
+      &gEfiSmmIoTrapDispatch2ProtocolGuid,
+      DispatchFunction,
+      (UINTN)RETURN_ADDRESS (0),
+      RegisterContext,
+      sizeof (EFI_SMM_IO_TRAP_REGISTER_CONTEXT)
+      );
+  }
+  return Status;
+}
+
+/**
+  Unregister a child SMI source dispatch function with a parent SMM driver.
+
+  @param[in] This                 Pointer to the EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL instance.
+  @param[in] DispatchHandle       Handle of dispatch function to deregister.
+
+  @retval EFI_SUCCESS             The dispatch function has been successfully
+                                  unregistered and the SMI source has been disabled
+                                  if there are no other registered child dispatch
+                                  functions for this SMI source.
+  @retval EFI_INVALID_PARAMETER   Handle is invalid.
+  @retval EFI_ACCESS_DENIED       Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+IoTrapUnRegister (
+  IN CONST EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL    *This,
+  IN EFI_HANDLE                                  DispatchHandle
+  )
+{
+  IO_TRAP_RECORD *RecordToDelete;
+
+  RecordToDelete = IO_TRAP_RECORD_FROM_LINK (DispatchHandle);
+  SmiHandlerProfileUnregisterHandler (
+    &gIoTrapExDispatchProtocolGuid,
+    RecordToDelete->IoTrapCallback,
+    &RecordToDelete->Context,
+    sizeof (EFI_SMM_IO_TRAP_REGISTER_CONTEXT)
+    );
+  return IoTrapUnRegisterHelper (DispatchHandle);
+}
+
+/**
+  Register a new IO Trap Ex SMI dispatch function.
+
+  @param[in] This                 Pointer to the IO_TRAP_EX_DISPATCH_PROTOCOL instance.
+  @param[in] DispatchFunction     Pointer to dispatch function to be invoked for
+                                  this SMI source.
+  @param[in] RegisterContext      Pointer to the dispatch function's context.
+                                  The caller fills this context in before calling
+                                  the register function to indicate to the register
+                                  function the IO trap Ex SMI source for which the dispatch
+                                  function should be invoked.  This MUST not be NULL.
+  @param[out] DispatchHandle      Handle of dispatch function.
+
+  @retval EFI_SUCCESS             The dispatch function has been successfully
+                                  registered and the SMI source has been enabled.
+  @retval EFI_OUT_OF_RESOURCES    Insufficient resources are available
+  @retval EFI_INVALID_PARAMETER   Address requested is already in use.
+  @retval EFI_ACCESS_DENIED       Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+IoTrapExRegister (
+  IN  IO_TRAP_EX_DISPATCH_PROTOCOL  *This,
+  IN  IO_TRAP_EX_DISPATCH_CALLBACK  DispatchFunction,
+  IN  IO_TRAP_EX_REGISTER_CONTEXT   *RegisterContext,
+  OUT EFI_HANDLE                    *DispatchHandle
+  )
+{
+  EFI_STATUS Status;
+
+  DEBUG ((DEBUG_INFO, "PchSmmIoTrapExRegister\n"));
+  //
+  // Return error if length is less than 4 and not power of 2.
+  //
+  if ((RegisterContext->Length < 4) || ((RegisterContext->Length & (RegisterContext->Length - 1)) != 0)) {
+    DEBUG ((DEBUG_ERROR, "The Dispatch Length is not power of 2 \n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = IoTrapRegisterHelper (
+             DispatchHandle,
+             NULL,
+             DispatchFunction,
+             &(RegisterContext->Address),
+             RegisterContext->Length,
+             RegisterContext->Type,
+             RegisterContext->ByteEnable,
+             RegisterContext->ByteEnableMask);
+
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileRegisterHandler (
+      &gIoTrapExDispatchProtocolGuid,
+      (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction,
+      (UINTN)RETURN_ADDRESS (0),
+      RegisterContext,
+      sizeof (*RegisterContext)
+      );
+  }
+  return Status;
+}
+
+/**
+  Unregister a SMI source dispatch function.
+  This function is unsupported.
+
+  @param[in] This                 Pointer to the IO_TRAP_EX_DISPATCH_PROTOCOL instance.
+  @param[in] DispatchHandle       Handle of dispatch function to deregister.
+
+  @retval EFI_UNSUPPORTED         The function is unsupported.
+**/
+EFI_STATUS
+EFIAPI
+IoTrapExUnRegister (
+  IN IO_TRAP_EX_DISPATCH_PROTOCOL   *This,
+  IN EFI_HANDLE                     DispatchHandle
+  )
+{
+  IO_TRAP_RECORD *RecordToDelete;
+
+  RecordToDelete = IO_TRAP_RECORD_FROM_LINK (DispatchHandle);
+  SmiHandlerProfileUnregisterHandler (
+    &gIoTrapExDispatchProtocolGuid,
+    RecordToDelete->IoTrapCallback,
+    &RecordToDelete->Context,
+    sizeof (RecordToDelete->Context)
+    );
+  return IoTrapUnRegisterHelper (DispatchHandle);
+}
+
+/**
+  Pause IoTrap callback function.
+
+  This function disables the SMI enable of IoTrap according to the DispatchHandle,
+  which is returned by IoTrap callback registration. It only supports the DispatchHandle
+  with MergeDisable TRUE and address not zero.
+
+  NOTE: This call does not guarantee all pending IO cycles to be synchronized
+        and pending IO cycles issued before this call might not be trapped.
+
+  @param[in] This                 Pointer to the PCH_SMM_IO_TRAP_CONTROL_PROTOCOL instance.
+  @param[in] DispatchHandle       Handle of the child service to change state.
+
+  @retval EFI_SUCCESS             This operation is complete.
+  @retval EFI_INVALID_PARAMETER   The DispatchHandle is invalid.
+  @retval EFI_ACCESS_DENIED       The SMI status is alrady PAUSED.
+**/
+EFI_STATUS
+EFIAPI
+IoTrapControlPause (
+  IN PCH_SMM_IO_TRAP_CONTROL_PROTOCOL   *This,
+  IN EFI_HANDLE                         DispatchHandle
+  )
+{
+  IO_TRAP_RECORD                        *IoTrapRecord;
+  UINT32                                IoTrapRegLowDword;
+  UINT32                                IoTrapRegHighDword;
+  EFI_PHYSICAL_ADDRESS                  BaseAddress;
+  UINT32                                UsedLength;
+  UINT8                                 TrapHandlerNum;
+  BOOLEAN                               TempMergeDisable;
+  BOOLEAN                               DisableIoTrap;
+
+  if (DispatchHandle == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  IoTrapRecord = IO_TRAP_RECORD_FROM_LINK (DispatchHandle);
+
+  if (IoTrapRecord->Context.Address) {
+    TempMergeDisable =TRUE;
+  }else {
+    TempMergeDisable = FALSE;
+  }
+
+  if ((IoTrapRecord->Signature != IO_TRAP_RECORD_SIGNATURE) ||
+      (TempMergeDisable != TRUE)                            ||
+      (IoTrapRecord->Context.Address == 0)                  ||
+      (IoTrapRecord->Context.Length == 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  for (TrapHandlerNum = 0; TrapHandlerNum < IO_TRAP_HANDLER_NUM; TrapHandlerNum++) {
+    //
+    // This IoTrap register should be merge disabled.
+    //
+    if (mIoTrapData.Entry[TrapHandlerNum].MergeDisable != TRUE) {
+      continue;
+    }
+    IoTrapRegLowDword = PchPcrRead32 (PID_PSTH, R_PSTH_PCR_TRPREG0 + TrapHandlerNum * 8);
+    IoTrapRegHighDword = PchPcrRead32 (PID_PSTH, R_PSTH_PCR_TRPREG0 + TrapHandlerNum * 8 + 4);
+    //
+    // Depending on the usage, we will obtain the UsedLength and BaseAddress differently
+    // If the registered trap length is less than 4, we obtain the length from Byte Enable Mask
+    // In the other hand, we obtain the length from Address Mask
+    //
+    if (ByteEnableMaskFromHighDword (IoTrapRegHighDword) != 0xF) {
+      UsedLength = (UINT32) (HighBitSet32 (IoTrapRegHighDword & 0xF0) - LowBitSet32 (IoTrapRegHighDword & 0xF0) + 1);
+      BaseAddress = AddressFromLowDword (IoTrapRegLowDword) + LowBitSet32 (ByteEnableMaskFromHighDword (IoTrapRegHighDword));
+    } else {
+      UsedLength  = LengthFromLowDword (IoTrapRegLowDword);
+      BaseAddress = AddressFromLowDword (IoTrapRegLowDword);
+    }
+
+    //
+    // The address and length of record matches the IoTrap register's.
+    //
+    DisableIoTrap = FALSE;
+    if ((IoTrapRecord->IoTrapExCallback != NULL) &&
+        IsIoTrapExContentMatched (IoTrapRecord, IoTrapRegLowDword, IoTrapRegHighDword)) {
+      DisableIoTrap = TRUE;
+    } else if ((BaseAddress == IoTrapRecord->Context.Address) &&
+               (UsedLength  == IoTrapRecord->Context.Length )) {
+      DisableIoTrap = TRUE;
+    }
+
+    if (DisableIoTrap) {
+      //
+      // Check if status matched.
+      // If this is already Paused, return warning status.
+      //
+      if ((IoTrapRegLowDword & B_PSTH_PCR_TRPREG_TSE) == 0) {
+        return EFI_ACCESS_DENIED;
+      }
+      //
+      // Clear IoTrap register SMI enable bit
+      //
+      IoTrapRegLowDword &= (~B_PSTH_PCR_TRPREG_TSE);
+      SetIoTrapLowDword (TrapHandlerNum, IoTrapRegLowDword, FALSE);
+      //
+      // Also clear pending IOTRAP status.
+      //
+      ClearPendingIoTrapStatus (TrapHandlerNum);
+      return EFI_SUCCESS;
+    }
+  }
+  return EFI_INVALID_PARAMETER;
+}
+
+/**
+  Resume IoTrap callback function.
+
+  This function enables the SMI enable of IoTrap according to the DispatchHandle,
+  which is returned by IoTrap callback registration. It only supports the DispatchHandle
+  with MergeDisable TRUE and address not zero.
+
+  @param[in] This                 Pointer to the PCH_SMM_IO_TRAP_CONTROL_PROTOCOL instance.
+  @param[in] DispatchHandle       Handle of the child service to change state.
+
+  @retval EFI_SUCCESS             This operation is complete.
+  @retval EFI_INVALID_PARAMETER   The DispatchHandle is invalid.
+  @retval EFI_ACCESS_DENIED       The SMI status is alrady RESUMED.
+**/
+EFI_STATUS
+EFIAPI
+IoTrapControlResume (
+  IN PCH_SMM_IO_TRAP_CONTROL_PROTOCOL   *This,
+  IN EFI_HANDLE                         DispatchHandle
+  )
+{
+  IO_TRAP_RECORD                        *IoTrapRecord;
+  UINT32                                IoTrapRegLowDword;
+  UINT32                                IoTrapRegHighDword;
+  EFI_PHYSICAL_ADDRESS                  BaseAddress;
+  UINT32                                UsedLength;
+  UINT8                                 TrapHandlerNum;
+  BOOLEAN                               TempMergeDisable;
+  BOOLEAN                               EnableIoTrap;
+
+  if (DispatchHandle == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+  IoTrapRecord = IO_TRAP_RECORD_FROM_LINK (DispatchHandle);
+
+  if (IoTrapRecord->Context.Address) {
+    TempMergeDisable = TRUE;
+  }else {
+    TempMergeDisable = FALSE;
+  }
+
+  if ((IoTrapRecord->Signature != IO_TRAP_RECORD_SIGNATURE) ||
+      (TempMergeDisable != TRUE)          ||
+      (IoTrapRecord->Context.Address == 0)                  ||
+      (IoTrapRecord->Context.Length == 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  for (TrapHandlerNum = 0; TrapHandlerNum < IO_TRAP_HANDLER_NUM; TrapHandlerNum++) {
+    //
+    // This IoTrap register should be merge disabled.
+    //
+    if (mIoTrapData.Entry[TrapHandlerNum].MergeDisable != TRUE) {
+      continue;
+    }
+    IoTrapRegLowDword = PchPcrRead32 (PID_PSTH, R_PSTH_PCR_TRPREG0 + TrapHandlerNum * 8);
+    IoTrapRegHighDword = PchPcrRead32 (PID_PSTH, R_PSTH_PCR_TRPREG0 + TrapHandlerNum * 8 + 4);
+    //
+    // Depending on the usage, we will obtain the UsedLength and BaseAddress differently
+    // If the registered trap length is less than 4, we obtain the length from Byte Enable Mask
+    // In the other hand, we obtain the length from Address Mask
+    //
+    if (ByteEnableMaskFromHighDword (IoTrapRegHighDword) != 0xF) {
+      UsedLength  = (UINT32) (HighBitSet32 (IoTrapRegHighDword & 0xF0) - LowBitSet32 (IoTrapRegHighDword & 0xF0) + 1);
+      BaseAddress = AddressFromLowDword (IoTrapRegLowDword) + LowBitSet32 (ByteEnableMaskFromHighDword (IoTrapRegHighDword));
+    } else {
+      UsedLength  = LengthFromLowDword (IoTrapRegLowDword);
+      BaseAddress = AddressFromLowDword (IoTrapRegLowDword);
+    }
+
+    //
+    // The address and length of record matches the IoTrap register's.
+    //
+    EnableIoTrap = FALSE;
+    if ((IoTrapRecord->IoTrapExCallback != NULL) &&
+        IsIoTrapExContentMatched (IoTrapRecord, IoTrapRegLowDword, IoTrapRegHighDword)) {
+      EnableIoTrap = TRUE;
+    } else if ((BaseAddress == IoTrapRecord->Context.Address) &&
+               (UsedLength  == IoTrapRecord->Context.Length )) {
+      EnableIoTrap = TRUE;
+    }
+
+    if (EnableIoTrap) {
+      //
+      // Check if status matched.
+      // If this is already Resume, return warning status.
+      //
+      if ((IoTrapRegLowDword & B_PSTH_PCR_TRPREG_TSE) != 0) {
+        return EFI_ACCESS_DENIED;
+      }
+      //
+      // Set IoTrap register SMI enable bit
+      //
+      IoTrapRegLowDword |= (B_PSTH_PCR_TRPREG_TSE);
+      SetIoTrapLowDword (TrapHandlerNum, IoTrapRegLowDword, FALSE);
+      return EFI_SUCCESS;
+    }
+  }
+  return EFI_INVALID_PARAMETER;
+}
+
+/**
+  The IoTrap module abstracts PCH I/O trapping capabilities for other drivers.
+  This driver manages the limited I/O trap resources.
+
+  @param[in] ImageHandle                Image handle for this driver image
+
+  @retval EFI_SUCCESS                   Driver initialization completed successfully
+**/
+EFI_STATUS
+EFIAPI
+InstallIoTrap (
+  IN EFI_HANDLE                         ImageHandle
+  )
+{
+  EFI_STATUS             Status;
+  PCH_NVS_AREA_PROTOCOL  *PchNvsAreaProtocol;
+  UINTN                  TrapHandlerNum;
+
+  //
+  // Initialize the EFI SMM driver library
+  //
+  mDriverImageHandle = ImageHandle;
+
+  //
+  // Initialize the IO TRAP protocol we produce
+  //
+  mIoTrapData.Signature = IO_TRAP_INSTANCE_SIGNATURE;
+  mIoTrapData.EfiSmmIoTrapDispatchProtocol.Register   = IoTrapRegister;
+  mIoTrapData.EfiSmmIoTrapDispatchProtocol.UnRegister = IoTrapUnRegister;
+
+  //
+  // Initialize the IO TRAP EX protocol
+  //
+  mIoTrapData.IoTrapExDispatchProtocol.Register       = IoTrapExRegister;
+  mIoTrapData.IoTrapExDispatchProtocol.UnRegister     = IoTrapExUnRegister;
+
+  //
+  // Initialize the IO TRAP control protocol.
+  //
+  mIoTrapData.PchSmmIoTrapControlProtocol.Pause       = IoTrapControlPause;
+  mIoTrapData.PchSmmIoTrapControlProtocol.Resume      = IoTrapControlResume;
+
+  for (TrapHandlerNum = 0; TrapHandlerNum < IO_TRAP_HANDLER_NUM; TrapHandlerNum++) {
+    //
+    // Initialize IO TRAP Callback DataBase
+    //
+    InitializeListHead (&(mIoTrapData.Entry[TrapHandlerNum].CallbackDataBase));
+  }
+  mIoTrapData.Entry[0].CallbackDispatcher = IoTrapDispatcher0;
+  mIoTrapData.Entry[1].CallbackDispatcher = IoTrapDispatcher1;
+  mIoTrapData.Entry[2].CallbackDispatcher = IoTrapDispatcher2;
+  mIoTrapData.Entry[3].CallbackDispatcher = IoTrapDispatcher3;
+
+  //
+  // Get address of PchNvs structure for later use
+  //
+  Status = gBS->LocateProtocol (&gPchNvsAreaProtocolGuid, NULL, (VOID **) &PchNvsAreaProtocol);
+  ASSERT_EFI_ERROR (Status);
+  mPchNvsArea = PchNvsAreaProtocol->Area;
+
+  //
+  // Install protocol interface
+  //
+  mIoTrapData.Handle = NULL;
+  Status = gSmst->SmmInstallProtocolInterface (
+                    &mIoTrapData.Handle,
+                    &gEfiSmmIoTrapDispatch2ProtocolGuid,
+                    EFI_NATIVE_INTERFACE,
+                    &mIoTrapData.EfiSmmIoTrapDispatchProtocol
+                    );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gSmst->SmmInstallProtocolInterface (
+                    &mIoTrapData.Handle,
+                    &gIoTrapExDispatchProtocolGuid,
+                    EFI_NATIVE_INTERFACE,
+                    &mIoTrapData.IoTrapExDispatchProtocol
+                    );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gSmst->SmmInstallProtocolInterface (
+                    &mIoTrapData.Handle,
+                    &gPchSmmIoTrapControlGuid,
+                    EFI_NATIVE_INTERFACE,
+                    &mIoTrapData.PchSmmIoTrapControlProtocol
+                    );
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.h
new file mode 100644
index 0000000000..e69d2e2d4d
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/IoTrap.h
@@ -0,0 +1,226 @@
+/** @file
+  Defines and prototypes for the IoTrap SMM driver
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _IO_TRAP_H_
+#define _IO_TRAP_H_
+
+//
+// Include files
+//
+#include <Library/S3BootScriptLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Protocol/SmmIoTrapDispatch2.h>
+#include <Protocol/PchSmmIoTrapControl.h>
+#include <Protocol/IoTrapExDispatch.h>
+
+#define IO_TRAP_HANDLER_NUM 4
+
+//
+// Driver private data
+//
+#define IO_TRAP_INSTANCE_SIGNATURE  SIGNATURE_32 ('I', 'O', 'T', 'P')
+
+typedef struct {
+  EFI_HANDLE                            IoTrapHandle;
+  /**
+    The callback linked list for all "merged" IoTrap callbacks.
+  **/
+  LIST_ENTRY                            CallbackDataBase;
+  /**
+    The IoTrap IO range used length tracking for "merged" IoTrap register.
+  **/
+  UINT32                                TrapUsedLength;
+  /**
+    Determine if IoTrap can be merged with other IoTrap callbacks.
+    If MergeDisable is TRUE, then there is only one callback function for one IoTrap register.
+    If MergeDisable is FALSE, then there are multiple callbacks in the "CallbackDataBase" for one IoTrap register.
+  **/
+  BOOLEAN                               MergeDisable;
+  /**
+    Indicator of the resource tracking in ACPI.
+    If the registration address is not 0, it's caller's responsibility to reserve the IO resource in ACPI.
+  **/
+  BOOLEAN                               ReservedAcpiIoResource;
+  /**
+    Dispatcher for each IoTrap register.
+  **/
+  PCH_SMI_DISPATCH_CALLBACK             CallbackDispatcher;
+} IO_TRAP_ENTRY_ATTRIBUTES;
+
+typedef struct {
+  UINT32                                Signature;
+  EFI_HANDLE                            Handle;
+  EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL    EfiSmmIoTrapDispatchProtocol;
+  PCH_SMM_IO_TRAP_CONTROL_PROTOCOL      PchSmmIoTrapControlProtocol;        ///< Protocol for runtime control the IoTrap state
+  IO_TRAP_EX_DISPATCH_PROTOCOL          IoTrapExDispatchProtocol;           ///< Protocol for IoTrap Extension
+  IO_TRAP_ENTRY_ATTRIBUTES              Entry[IO_TRAP_HANDLER_NUM];
+} IO_TRAP_INSTANCE;
+
+#define IO_TRAP_INSTANCE_FROM_THIS(a) CR (a, IO_TRAP_INSTANCE, EfiSmmIoTrapDispatchProtocol, IO_TRAP_INSTANCE_SIGNATURE)
+
+///
+/// "IOTRAP" RECORD
+/// Linked list data structures
+///
+#define IO_TRAP_RECORD_SIGNATURE  SIGNATURE_32 ('I', 'T', 'R', 'C')
+
+typedef struct _IO_TRAP_RECORD {
+  UINT32                                    Signature;
+  LIST_ENTRY                                Link;
+  IO_TRAP_EX_REGISTER_CONTEXT               Context;
+  /**
+    The callback function of IoTrap protocol.
+    This also indicate it's the record for IoTrapProtocol.
+    Only one of IoTrapCallback or IoTrapExCallback is valid at a time.
+  **/
+  EFI_SMM_HANDLER_ENTRY_POINT2              IoTrapCallback;
+  /**
+    The callback function of IoTrapEx protocol
+    This also indicate it's the record for IoTrapExProtocol.
+    Only one of IoTrapCallback or IoTrapExCallback is valid at a time.
+  **/
+  IO_TRAP_EX_DISPATCH_CALLBACK              IoTrapExCallback;
+  UINT8                                     IoTrapNumber;
+} IO_TRAP_RECORD;
+
+#define IO_TRAP_RECORD_FROM_LINK(_record) CR (_record, IO_TRAP_RECORD, Link, IO_TRAP_RECORD_SIGNATURE)
+
+//
+// Prototypes
+//
+/**
+  The IoTrap module abstracts PCH I/O trapping capabilities for other drivers.
+  This driver manages the limited I/O trap resources.
+
+  @param[in] ImageHandle                Image handle for this driver image
+
+  @retval EFI_SUCCESS                   Driver initialization completed successfully
+**/
+EFI_STATUS
+EFIAPI
+InstallIoTrap (
+  IN EFI_HANDLE                     ImageHandle
+  );
+
+/**
+  Register a new IO Trap SMI dispatch function with a parent SMM driver.
+  The caller will provide information about the IO trap characteristics via
+  the context.  This includes base address, length, read vs. r/w, etc.
+  This function will autoallocate IO base address from a common pool if the base address is 0,
+  and the RegisterContext Address field will be updated.
+  The service will not perform GCD allocation if the base address is non-zero.
+  In this case, the caller is responsible for the existence and allocation of the
+  specific IO range.
+  This function looks for the suitable handler and Register a new IoTrap handler
+  if the IO Trap handler is not used. It also enable the IO Trap Range to generate
+  SMI.
+
+  @param[in] This                 Pointer to the  EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL instance.
+  @param[in] DispatchFunction     Pointer to dispatch function to be invoked for
+                                  this SMI source.
+  @param[in, out] RegisterContext Pointer to the dispatch function's context.
+                                  The caller fills this context in before calling
+                                  the register function to indicate to the register
+                                  function the IO trap SMI source for which the dispatch
+                                  function should be invoked.  This may not be NULL.
+                                  If the registration address is not 0, it's caller's responsibility
+                                  to reserve the IO resource in ACPI.
+  @param[out] DispatchHandle      Handle of dispatch function, for when interfacing
+                                  with the parent SMM driver, will be the address of linked
+                                  list link in the call back record.  This may not be NULL.
+
+  @retval EFI_SUCCESS             The dispatch function has been successfully
+                                  registered and the SMI source has been enabled.
+  @retval EFI_DEVICE_ERROR        The driver was unable to enable the SMI source.
+  @retval EFI_OUT_OF_RESOURCES    Insufficient resources are available
+  @retval EFI_INVALID_PARAMETER   Address requested is already in use.
+  @retval EFI_ACCESS_DENIED       Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+IoTrapRegister (
+  IN  CONST   EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL     *This,
+  IN          EFI_SMM_HANDLER_ENTRY_POINT2           DispatchFunction,
+  IN OUT      EFI_SMM_IO_TRAP_REGISTER_CONTEXT       *RegisterContext,
+  OUT EFI_HANDLE                                      *DispatchHandle
+  );
+
+/**
+  Unregister a child SMI source dispatch function with a parent SMM driver.
+
+  @param[in] This                 Pointer to the  EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL instance.
+  @param[in] DispatchHandle       Handle of dispatch function to deregister.
+
+  @retval EFI_SUCCESS             The dispatch function has been successfully
+                                  unregistered and the SMI source has been disabled
+                                  if there are no other registered child dispatch
+                                  functions for this SMI source.
+  @retval EFI_INVALID_PARAMETER   Handle is invalid.
+  @retval EFI_ACCESS_DENIED       Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+IoTrapUnRegister (
+  IN CONST  EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL    *This,
+  IN EFI_HANDLE                                   DispatchHandle
+  );
+
+/**
+  This I/O Trap SMI handler invokes the ACPI reference code to handle the SMI.
+  It currently assumes it owns all of the IO trap SMI.
+
+  @param[in] DispatchHandle           Not used
+
+**/
+VOID
+EFIAPI
+IoTrapCallback (
+  IN  EFI_HANDLE                      DispatchHandle
+  );
+
+/**
+  Pause IoTrap callback function.
+
+  This function disables the SMI enable of IoTrap according to the DispatchHandle,
+  which is returned by IoTrap callback registration. It only supports the DispatchHandle
+  with MergeDisable TRUE and address not zero.
+
+  @param[in] This                 Pointer to the PCH_SMM_IO_TRAP_CONTROL_PROTOCOL instance.
+  @param[in] DispatchHandle       Handle of the child service to change state.
+
+  @retval EFI_SUCCESS             This operation is complete.
+  @retval EFI_INVALID_PARAMETER   The DispatchHandle is invalid.
+  @retval EFI_ACCESS_DENIED       The SMI status is alrady PAUSED.
+**/
+EFI_STATUS
+EFIAPI
+IoTrapControlPause (
+  IN PCH_SMM_IO_TRAP_CONTROL_PROTOCOL * This,
+  IN EFI_HANDLE                       DispatchHandle
+  );
+
+/**
+  Resume IoTrap callback function.
+
+  This function enables the SMI enable of IoTrap according to the DispatchHandle,
+  which is returned by IoTrap callback registration. It only supports the DispatchHandle
+  with MergeDisable TRUE and address not zero.
+
+  @param[in] This                 Pointer to the PCH_SMM_IO_TRAP_CONTROL_PROTOCOL instance.
+  @param[in] DispatchHandle       Handle of the child service to change state.
+
+  @retval EFI_SUCCESS             This operation is complete.
+  @retval EFI_INVALID_PARAMETER   The DispatchHandle is invalid.
+  @retval EFI_ACCESS_DENIED       The SMI status is alrady RESUMED.
+**/
+EFI_STATUS
+EFIAPI
+IoTrapControlResume (
+  IN PCH_SMM_IO_TRAP_CONTROL_PROTOCOL * This,
+  IN EFI_HANDLE                       DispatchHandle
+  );
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatch.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatch.c
new file mode 100644
index 0000000000..affbe94eb7
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatch.c
@@ -0,0 +1,2442 @@
+/** @file
+  This function handle the register/unregister of PCH specific SMI events.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "PchSmmHelpers.h"
+#include <Library/SmiHandlerProfileLib.h>
+#include <Register/PchRegs.h>
+#include <Register/PchPcrRegs.h>
+#include <Register/PmcRegs.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/SpiRegs.h>
+#include <Register/PchPcieRpRegs.h>
+#include <Register/PchRegsPsth.h>
+#include <Library/PchPciBdfLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <PchBdfAssignment.h>
+#include "PchSmiHelper.h"
+
+/**
+  The internal function used to create and insert a database record
+  for SMI record of Pch Smi types.
+
+  @param[in]  SrcDesc                   The pointer to the SMI source description
+  @param[in]  DispatchFunction          Pointer to dispatch function to be invoked for this SMI source
+  @param[in]  PchSmiType                Specific SMI type of PCH SMI
+  @param[out] DispatchHandle            Handle of dispatch function to register.
+
+  @retval EFI_INVALID_PARAMETER         Error with NULL SMI source description
+  @retval EFI_OUT_OF_RESOURCES          Fail to allocate pool for database record
+  @retval EFI_SUCCESS                   The database record is created successfully.
+**/
+EFI_STATUS
+PchSmiRecordInsert (
+  IN  CONST PCH_SMM_SOURCE_DESC         *SrcDesc,
+  IN  PCH_SMI_CALLBACK_FUNCTIONS        DispatchFunction,
+  IN  PCH_SMI_TYPES                     PchSmiType,
+  OUT EFI_HANDLE                        *DispatchHandle
+  )
+{
+  EFI_STATUS                            Status;
+  DATABASE_RECORD                       Record;
+
+  if (SrcDesc == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ZeroMem (&Record, sizeof (DATABASE_RECORD));
+  //
+  // Gather information about the registration request
+  //
+  Record.Signature                      = DATABASE_RECORD_SIGNATURE;
+  Record.PchSmiCallback                 = DispatchFunction;
+  Record.ProtocolType                   = PchSmiDispatchType;
+  Record.PchSmiType                     = PchSmiType;
+
+  CopyMem (&Record.SrcDesc, SrcDesc, sizeof (PCH_SMM_SOURCE_DESC));
+  Status = SmmCoreInsertRecord (
+             &Record,
+             DispatchHandle
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+
+//
+// TCO_STS bit that needs to be cleared
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mDescSrcTcoSts = {
+  PCH_SMM_NO_FLAGS,
+  {
+    NULL_BIT_DESC_INITIALIZER,
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_STS}
+      },
+      S_ACPI_IO_SMI_STS,
+      N_ACPI_IO_SMI_STS_TCO
+    }
+  },
+  NULL_BIT_DESC_INITIALIZER
+};
+
+/**
+  Clear the TCO SMI status bit and block after the SMI handling is done
+
+  @param[in] SrcDesc                    Pointer to the PCH SMI source description table
+
+**/
+VOID
+EFIAPI
+PchTcoSmiClearSourceAndBlock (
+  CONST PCH_SMM_SOURCE_DESC             *SrcDesc
+  )
+{
+  PchSmmClearSourceAndBlock (SrcDesc);
+  //
+  // Any TCO-based status bits require special handling.
+  // SMI_STS.TCO_STS must be cleared in addition to the status bit in the TCO registers
+  //
+  PchSmmClearSource (&mDescSrcTcoSts);
+}
+
+/**
+  Clear the TCO SMI status bit after the SMI handling is done
+
+  @param[in] SrcDesc                    Pointer to the PCH SMI source description table
+
+**/
+VOID
+EFIAPI
+PchTcoSmiClearSource (
+  CONST PCH_SMM_SOURCE_DESC             *SrcDesc
+  )
+{
+  PchSmmClearSource (SrcDesc);
+  //
+  // Any TCO-based status bits require special handling.
+  // SMI_STS.TCO_STS must be cleared in addition to the status bit in the TCO registers
+  //
+  PchSmmClearSource (&mDescSrcTcoSts);
+}
+
+/**
+  Initialize Source descriptor structure
+
+   @param[in] SrcDesc                    Pointer to the PCH SMI source description table
+
+**/
+VOID
+EFIAPI
+NullInitSourceDesc (
+   PCH_SMM_SOURCE_DESC                   *SrcDesc
+   )
+{
+  ZeroMem (SrcDesc, sizeof (PCH_SMM_SOURCE_DESC));
+  SrcDesc->En[0].Reg.Type = PCH_SMM_ADDR_TYPE_NULL;
+  SrcDesc->En[1].Reg.Type = PCH_SMM_ADDR_TYPE_NULL;
+  SrcDesc->Sts[0].Reg.Type = PCH_SMM_ADDR_TYPE_NULL;
+  SrcDesc->PmcSmiSts.Reg.Type = PCH_SMM_ADDR_TYPE_NULL;
+}
+
+//
+// Mch srcdesc
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mSrcDescMch = {
+  PCH_SMM_NO_FLAGS,
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_EN}
+      },
+      S_ACPI_IO_SMI_EN,
+      N_ACPI_IO_SMI_EN_TCO
+    },
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        TCO_ADDR_TYPE,
+        {R_TCO_IO_TCO1_STS}
+      },
+      S_TCO_IO_TCO1_STS,
+      N_TCO_IO_TCO1_STS_DMISMI
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_TCO
+  }
+};
+
+/**
+  The register function used to register SMI handler of MCH event.
+
+  @param[in]  This                      The pointer to the protocol itself
+  @param[in]  DispatchFunction          Pointer to dispatch function to be invoked for this SMI source
+  @param[out] DispatchHandle            Handle of dispatch function to register.
+
+  @retval EFI_INVALID_PARAMETER         Error with NULL SMI source description
+  @retval EFI_OUT_OF_RESOURCES          Fail to allocate pool for database record
+  @retval EFI_SUCCESS                   The database record is created successfully.
+  @retval EFI_ACCESS_DENIED             Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+PchTcoSmiMchRegister (
+  IN  PCH_TCO_SMI_DISPATCH_PROTOCOL     *This,
+  IN  PCH_TCO_SMI_DISPATCH_CALLBACK     DispatchFunction,
+  OUT EFI_HANDLE                        *DispatchHandle
+  )
+{
+  EFI_STATUS                            Status;
+  DATABASE_RECORD                       *Record;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = PchSmiRecordInsert (
+             &mSrcDescMch,
+             (PCH_SMI_CALLBACK_FUNCTIONS) DispatchFunction,
+             PchTcoSmiMchType,
+             DispatchHandle
+             );
+  if (!EFI_ERROR (Status)) {
+    Record = DATABASE_RECORD_FROM_LINK (*DispatchHandle);
+    Record->ClearSource = PchTcoSmiClearSource;
+    PchSmmClearSource (&Record->SrcDesc);
+    PchSmmEnableSource (&Record->SrcDesc);
+    SmiHandlerProfileRegisterHandler (&gPchTcoSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  return Status;
+}
+
+//
+// TcoTimeout srcdesc
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mSrcDescTcoTimeout = {
+  PCH_SMM_NO_FLAGS,
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_EN}
+      },
+      S_ACPI_IO_SMI_EN,
+      N_ACPI_IO_SMI_EN_TCO
+    },
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        TCO_ADDR_TYPE,
+        {R_TCO_IO_TCO1_STS}
+      },
+      S_TCO_IO_TCO1_STS,
+      N_TCO_IO_TCO1_STS_TIMEOUT
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_TCO
+  }
+};
+
+/**
+  The register function used to register SMI handler of TcoTimeout event.
+
+  @param[in]  This                      The pointer to the protocol itself
+  @param[in]  DispatchFunction          Pointer to dispatch function to be invoked for this SMI source
+  @param[out] DispatchHandle            Handle of dispatch function to register.
+
+  @retval EFI_INVALID_PARAMETER         Error with NULL SMI source description
+  @retval EFI_OUT_OF_RESOURCES          Fail to allocate pool for database record
+  @retval EFI_SUCCESS                   The database record is created successfully.
+  @retval EFI_ACCESS_DENIED             Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+PchTcoSmiTcoTimeoutRegister (
+  IN  PCH_TCO_SMI_DISPATCH_PROTOCOL     *This,
+  IN  PCH_TCO_SMI_DISPATCH_CALLBACK     DispatchFunction,
+  OUT EFI_HANDLE                        *DispatchHandle
+  )
+{
+  EFI_STATUS                            Status;
+  DATABASE_RECORD                       *Record;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = PchSmiRecordInsert (
+             &mSrcDescTcoTimeout,
+             (PCH_SMI_CALLBACK_FUNCTIONS) DispatchFunction,
+             PchTcoSmiTcoTimeoutType,
+             DispatchHandle
+             );
+  if (!EFI_ERROR (Status)) {
+    Record = DATABASE_RECORD_FROM_LINK (*DispatchHandle);
+    Record->ClearSource = PchTcoSmiClearSource;
+    PchSmmClearSource (&Record->SrcDesc);
+    PchSmmEnableSource (&Record->SrcDesc);
+    SmiHandlerProfileRegisterHandler (&gPchTcoSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  return Status;
+}
+
+//
+// OsTco srcdesc
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mSrcDescOsTco = {
+  PCH_SMM_NO_FLAGS,
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_EN}
+      },
+      S_ACPI_IO_SMI_EN,
+      N_ACPI_IO_SMI_EN_TCO
+    },
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        TCO_ADDR_TYPE,
+        {R_TCO_IO_TCO1_STS}
+      },
+      S_TCO_IO_TCO1_STS,
+      N_TCO_IO_TCO1_STS_SW_TCO_SMI
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_TCO
+  }
+};
+
+/**
+  The register function used to register SMI handler of OS TCO event.
+
+  @param[in]  This                      The pointer to the protocol itself
+  @param[in]  DispatchFunction          Pointer to dispatch function to be invoked for this SMI source
+  @param[out] DispatchHandle            Handle of dispatch function to register.
+
+  @retval EFI_INVALID_PARAMETER         Error with NULL SMI source description
+  @retval EFI_OUT_OF_RESOURCES          Fail to allocate pool for database record
+  @retval EFI_SUCCESS                   The database record is created successfully.
+  @retval EFI_ACCESS_DENIED             Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+PchTcoSmiOsTcoRegister (
+  IN  PCH_TCO_SMI_DISPATCH_PROTOCOL     *This,
+  IN  PCH_TCO_SMI_DISPATCH_CALLBACK     DispatchFunction,
+  OUT EFI_HANDLE                        *DispatchHandle
+  )
+{
+  EFI_STATUS                            Status;
+  DATABASE_RECORD                       *Record;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = PchSmiRecordInsert (
+             &mSrcDescOsTco,
+             (PCH_SMI_CALLBACK_FUNCTIONS) DispatchFunction,
+             PchTcoSmiOsTcoType,
+             DispatchHandle
+             );
+  if (!EFI_ERROR (Status)) {
+    Record = DATABASE_RECORD_FROM_LINK (*DispatchHandle);
+    Record->ClearSource = PchTcoSmiClearSource;
+    PchSmmClearSource (&Record->SrcDesc);
+    PchSmmEnableSource (&Record->SrcDesc);
+    SmiHandlerProfileRegisterHandler (&gPchTcoSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  return Status;
+}
+
+//
+// Nmi
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mSrcDescNmi = {
+  PCH_SMM_NO_FLAGS,
+  {
+    {
+      {
+        TCO_ADDR_TYPE,
+        {R_TCO_IO_TCO1_CNT}
+      },
+      S_TCO_IO_TCO1_CNT,
+      N_TCO_IO_TCO1_CNT_NMI2SMI_EN
+    },
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        TCO_ADDR_TYPE,
+        {R_TCO_IO_TCO1_STS}
+      },
+      S_TCO_IO_TCO1_STS,
+      N_TCO_IO_TCO1_STS_NMI2SMI
+    }
+  },
+  //
+  // NOTE: The status of NMI2SMI won't reflect to PMC SMI_STS.
+  //       So skip the top level status check and check the TCO1_STS directly.
+  //
+  NULL_BIT_DESC_INITIALIZER
+};
+
+/**
+  The register function used to register SMI handler of NMI event.
+
+  @param[in]  This                      The pointer to the protocol itself
+  @param[in]  DispatchFunction          Pointer to dispatch function to be invoked for this SMI source
+  @param[out] DispatchHandle            Handle of dispatch function to register.
+
+  @retval EFI_INVALID_PARAMETER         Error with NULL SMI source description
+  @retval EFI_OUT_OF_RESOURCES          Fail to allocate pool for database record
+  @retval EFI_SUCCESS                   The database record is created successfully.
+  @retval EFI_ACCESS_DENIED             Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+PchTcoSmiNmiRegister (
+  IN  PCH_TCO_SMI_DISPATCH_PROTOCOL     *This,
+  IN  PCH_TCO_SMI_DISPATCH_CALLBACK     DispatchFunction,
+  OUT EFI_HANDLE                        *DispatchHandle
+  )
+{
+  EFI_STATUS                            Status;
+  DATABASE_RECORD                       *Record;
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = PchSmiRecordInsert (
+             &mSrcDescNmi,
+             (PCH_SMI_CALLBACK_FUNCTIONS) DispatchFunction,
+             PchTcoSmiNmiType,
+             DispatchHandle
+             );
+  if (!EFI_ERROR (Status)) {
+    Record = DATABASE_RECORD_FROM_LINK (*DispatchHandle);
+    Record->ClearSource = PchTcoSmiClearSource;
+    PchSmmClearSource (&Record->SrcDesc);
+    PchSmmEnableSource (&Record->SrcDesc);
+    SmiHandlerProfileRegisterHandler (&gPchTcoSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  return Status;
+}
+
+//
+// IntruderDetect srcdesc
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mSrcDescIntruderDet = {
+  PCH_SMM_NO_FLAGS,
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_EN}
+      },
+      S_ACPI_IO_SMI_EN,
+      N_ACPI_IO_SMI_EN_TCO
+    },
+    {
+      {
+        TCO_ADDR_TYPE,
+        {R_TCO_IO_TCO2_CNT}
+      },
+      S_TCO_IO_TCO2_CNT,
+      N_TCO_IO_TCO2_CNT_INTRD_SEL
+    }
+  },
+  {
+    {
+      {
+        TCO_ADDR_TYPE,
+        {R_TCO_IO_TCO2_STS}
+      },
+      S_TCO_IO_TCO2_STS,
+      N_TCO_IO_TCO2_STS_INTRD_DET
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_TCO
+  }
+};
+
+/**
+  The register function used to register SMI handler of Intruder Detect event.
+
+  @param[in]  This                      The pointer to the protocol itself
+  @param[in]  DispatchFunction          Pointer to dispatch function to be invoked for this SMI source
+  @param[out] DispatchHandle            Handle of dispatch function to register.
+
+  @retval EFI_INVALID_PARAMETER         Error with NULL SMI source description
+  @retval EFI_OUT_OF_RESOURCES          Fail to allocate pool for database record
+  @retval EFI_SUCCESS                   The database record is created successfully.
+  @retval EFI_ACCESS_DENIED             Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+PchTcoSmiIntruderDetRegister (
+  IN  PCH_TCO_SMI_DISPATCH_PROTOCOL     *This,
+  IN  PCH_TCO_SMI_DISPATCH_CALLBACK     DispatchFunction,
+  OUT EFI_HANDLE                        *DispatchHandle
+  )
+{
+  EFI_STATUS                            Status;
+  DATABASE_RECORD                       *Record;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = PchSmiRecordInsert (
+             &mSrcDescIntruderDet,
+             (PCH_SMI_CALLBACK_FUNCTIONS) DispatchFunction,
+             PchTcoSmiIntruderDetectType,
+             DispatchHandle
+             );
+  if (!EFI_ERROR (Status)) {
+    Record = DATABASE_RECORD_FROM_LINK (*DispatchHandle);
+    Record->ClearSource = PchTcoSmiClearSourceAndBlock;
+    PchSmmClearSource (&Record->SrcDesc);
+    PchSmmEnableSource (&Record->SrcDesc);
+    SmiHandlerProfileRegisterHandler (&gPchTcoSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  return Status;
+}
+
+//
+// SpiBiosWp srcdesc
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mSrcDescSpiBiosWp = {
+  PCH_SMM_NO_FLAGS,
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_EN}
+      },
+      S_ACPI_IO_SMI_EN,
+      N_ACPI_IO_SMI_EN_TCO
+    },
+    {
+      {
+        PCIE_ADDR_TYPE,
+        { (
+          (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+          (PCI_DEVICE_NUMBER_PCH_SPI << 19) |
+          (PCI_FUNCTION_NUMBER_PCH_SPI << 16) |
+          R_SPI_CFG_BC
+        ) }
+      },
+      S_SPI_CFG_BC,
+      N_SPI_CFG_BC_BLE
+    },
+  },
+  {
+    {
+      {
+        PCIE_ADDR_TYPE,
+        { (
+          (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+          (PCI_DEVICE_NUMBER_PCH_SPI << 19) |
+          (PCI_FUNCTION_NUMBER_PCH_SPI << 16) |
+          R_SPI_CFG_BC
+        ) }
+      },
+      S_SPI_CFG_BC,
+      N_SPI_CFG_BC_SYNC_SS
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_TCO
+  }
+};
+
+/**
+  Special handling for SPI Write Protect
+
+  @param[in]  SrcDesc   Not used
+**/
+VOID
+EFIAPI
+PchTcoSpiWpClearSource (
+  CONST PCH_SMM_SOURCE_DESC             *SrcDesc
+  )
+{
+  UINT64 SpiRegBase;
+  UINT32 BiosControl;
+  UINT32 Timeout;
+
+  SpiRegBase = SpiPciCfgBase ();
+  PciSegmentAndThenOr32 (
+    SpiRegBase + R_SPI_CFG_BC,
+    (UINT32) ~B_SPI_CFG_BC_ASYNC_SS,
+    B_SPI_CFG_BC_SYNC_SS
+    );
+  //
+  // Ensure the SYNC is cleared
+  //
+  Timeout = 1000;
+  do {
+    BiosControl = PciSegmentRead32 (SpiRegBase + R_SPI_CFG_BC);
+    Timeout--;
+  } while ((BiosControl & B_SPI_CFG_BC_SYNC_SS) && (Timeout > 0));
+
+  //
+  // Any TCO-based status bits require special handling.
+  // SMI_STS.TCO_STS must be cleared in addition to the status bit in the TCO registers
+  //
+  PchSmmClearSource (&mDescSrcTcoSts);
+}
+
+/**
+  Set SMI_EN_TCO to enable TCO SMI.
+**/
+STATIC
+VOID
+PchSetSmiEnTco (
+  VOID
+  )
+{
+  IoOr32 (mAcpiBaseAddr + R_ACPI_IO_SMI_EN, B_ACPI_IO_SMI_EN_TCO);
+}
+
+/**
+  The register function used to register SMI handler of BIOS write protect event.
+
+  @param[in]  This                      The pointer to the protocol itself
+  @param[in]  DispatchFunction          Pointer to dispatch function to be invoked for this SMI source
+  @param[out] DispatchHandle            Handle of dispatch function to register.
+
+  @retval EFI_INVALID_PARAMETER         Error with NULL SMI source description
+  @retval EFI_OUT_OF_RESOURCES          Fail to allocate pool for database record
+  @retval EFI_SUCCESS                   The database record is created successfully.
+  @retval EFI_ACCESS_DENIED             Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+PchTcoSmiSpiBiosWpRegister (
+  IN  PCH_TCO_SMI_DISPATCH_PROTOCOL     *This,
+  IN  PCH_TCO_SMI_DISPATCH_CALLBACK     DispatchFunction,
+  OUT EFI_HANDLE                        *DispatchHandle
+  )
+{
+  EFI_STATUS                            Status;
+  DATABASE_RECORD                       *Record;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = PchSmiRecordInsert (
+             &mSrcDescSpiBiosWp,
+             (PCH_SMI_CALLBACK_FUNCTIONS) DispatchFunction,
+             PchTcoSmiSpiBiosWpType,
+             DispatchHandle
+             );
+  if (!EFI_ERROR (Status)) {
+    Record = DATABASE_RECORD_FROM_LINK (*DispatchHandle);
+    Record->ClearSource = PchTcoSpiWpClearSource;
+    PchTcoSpiWpClearSource (NULL);
+    //
+    // It doesn't enable the BIOSLOCK here. Enable it by policy in DXE.
+    // Only enable SMI_EN_TCO.
+    //
+    PchSetSmiEnTco ();
+    SmiHandlerProfileRegisterHandler (&gPchTcoSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  return Status;
+}
+
+//
+// LpcBiosWp srcdesc
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mSrcDescLpcBiosWp = {
+  PCH_SMM_NO_FLAGS,
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_EN}
+      },
+      S_ACPI_IO_SMI_EN,
+      N_ACPI_IO_SMI_EN_TCO
+    },
+    {
+      {
+        PCIE_ADDR_TYPE,
+        { (
+          (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+          (PCI_DEVICE_NUMBER_PCH_LPC << 19) |
+          (PCI_FUNCTION_NUMBER_PCH_LPC << 16) |
+          R_LPC_CFG_BC
+        ) }
+      },
+      S_LPC_CFG_BC,
+      N_LPC_CFG_BC_LE
+    }
+  },
+  {
+    {
+      {
+        TCO_ADDR_TYPE,
+        {R_TCO_IO_TCO1_STS}
+      },
+      S_TCO_IO_TCO1_STS,
+      N_TCO_IO_TCO1_STS_BIOSWR
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_TCO
+  }
+};
+
+/**
+  The register function used to register SMI handler of LPC BIOS write protect event.
+
+  @param[in]  This                      The pointer to the protocol itself
+  @param[in]  DispatchFunction          Pointer to dispatch function to be invoked for this SMI source
+  @param[out] DispatchHandle            Handle of dispatch function to register.
+
+  @retval EFI_INVALID_PARAMETER         Error with NULL SMI source description
+  @retval EFI_OUT_OF_RESOURCES          Fail to allocate pool for database record
+  @retval EFI_SUCCESS                   The database record is created successfully.
+  @retval EFI_ACCESS_DENIED             Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+PchTcoSmiLpcBiosWpRegister (
+  IN  PCH_TCO_SMI_DISPATCH_PROTOCOL     *This,
+  IN  PCH_TCO_SMI_DISPATCH_CALLBACK     DispatchFunction,
+  OUT EFI_HANDLE                        *DispatchHandle
+  )
+{
+  EFI_STATUS                            Status;
+  DATABASE_RECORD                       *Record;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  if (IsEspiEnabled ()) {
+    //
+    // Status is D31F0's PCBC.BWPDS
+    //
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = PchSmiRecordInsert (
+             &mSrcDescLpcBiosWp,
+             (PCH_SMI_CALLBACK_FUNCTIONS) DispatchFunction,
+             PchTcoSmiLpcBiosWpType,
+             DispatchHandle
+             );
+  if (!EFI_ERROR (Status)) {
+    Record = DATABASE_RECORD_FROM_LINK (*DispatchHandle);
+    Record->ClearSource = PchTcoSmiClearSource;
+    PchSmmClearSource (&Record->SrcDesc);
+    //
+    // It doesn't enable the BIOSLOCK here. Enable it by policy in DXE.
+    // Only enable SMI_EN_TCO.
+    //
+    PchSetSmiEnTco ();
+    SmiHandlerProfileRegisterHandler (&gPchTcoSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  return Status;
+}
+
+//
+// NEWCENTURY_STS bit that needs to be cleared
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mSrcDescNewCentury = {
+  PCH_SMM_NO_FLAGS,
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_EN}
+      },
+      S_ACPI_IO_SMI_EN,
+      N_ACPI_IO_SMI_EN_TCO
+    },
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        TCO_ADDR_TYPE,
+        {R_TCO_IO_TCO1_STS}
+      },
+      S_TCO_IO_TCO1_STS,
+      N_TCO_IO_TCO1_STS_NEWCENTURY
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_TCO
+  }
+};
+
+/**
+  The register function used to register SMI handler of NEW CENTURY event.
+
+  @param[in]  This                      The pointer to the protocol itself
+  @param[in]  DispatchFunction          Pointer to dispatch function to be invoked for this SMI source
+  @param[out] DispatchHandle            Handle of dispatch function to register.
+
+  @retval EFI_INVALID_PARAMETER         Error with NULL SMI source description
+  @retval EFI_OUT_OF_RESOURCES          Fail to allocate pool for database record
+  @retval EFI_SUCCESS                   The database record is created successfully.
+  @retval EFI_ACCESS_DENIED             Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+PchTcoSmiNewCenturyRegister (
+  IN  PCH_TCO_SMI_DISPATCH_PROTOCOL     *This,
+  IN  PCH_TCO_SMI_DISPATCH_CALLBACK     DispatchFunction,
+  OUT EFI_HANDLE                        *DispatchHandle
+  )
+{
+  EFI_STATUS                            Status;
+  DATABASE_RECORD                       *Record;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = PchSmiRecordInsert (
+             &mSrcDescNewCentury,
+             (PCH_SMI_CALLBACK_FUNCTIONS) DispatchFunction,
+             PchTcoSmiNewCenturyType,
+             DispatchHandle
+             );
+  if (!EFI_ERROR (Status)) {
+    Record = DATABASE_RECORD_FROM_LINK (*DispatchHandle);
+    Record->ClearSource = PchTcoSmiClearSourceAndBlock;
+    PchSmmClearSource (&Record->SrcDesc);
+    PchSmmEnableSource (&Record->SrcDesc);
+    SmiHandlerProfileRegisterHandler (&gPchTcoSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  return Status;
+}
+
+/**
+  Unregister a child SMI source dispatch function with a parent SMM driver
+
+  @param[in] This                       Protocol instance pointer.
+  @param[in] DispatchHandle             Handle of dispatch function to deregister.
+
+  @retval EFI_SUCCESS                   The dispatch function has been successfully
+                                        unregistered and the SMI source has been disabled
+                                        if there are no other registered child dispatch
+                                        functions for this SMI source.
+  @retval EFI_INVALID_PARAMETER         Handle is invalid.
+  @retval EFI_ACCESS_DENIED             Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+PchTcoSmiUnRegister (
+  IN  PCH_TCO_SMI_DISPATCH_PROTOCOL     *This,
+  IN  EFI_HANDLE                        DispatchHandle
+  )
+{
+  DATABASE_RECORD                       *Record;
+  EFI_STATUS                            Status;
+
+  Record = DATABASE_RECORD_FROM_LINK (DispatchHandle);
+  if ((Record->SrcDesc.En[1].Reg.Type == ACPI_ADDR_TYPE) &&
+      (Record->SrcDesc.En[1].Reg.Data.pcie.Fields.Dev == SpiDevNumber ()) &&
+      (Record->SrcDesc.En[1].Reg.Data.pcie.Fields.Fnc == SpiFuncNumber ()) &&
+      (Record->SrcDesc.En[1].Reg.Data.pcie.Fields.Reg == R_SPI_CFG_BC) &&
+      (Record->SrcDesc.En[1].Bit == N_SPI_CFG_BC_BLE)) {
+    //
+    // SPI Write Protect cannot be disabled
+    //
+    return EFI_ACCESS_DENIED;
+  } else if ((Record->SrcDesc.En[1].Reg.Type == ACPI_ADDR_TYPE) &&
+             (Record->SrcDesc.En[1].Reg.Data.pcie.Fields.Dev == LpcDevNumber ()) &&
+             (Record->SrcDesc.En[1].Reg.Data.pcie.Fields.Fnc == LpcFuncNumber ()) &&
+             (Record->SrcDesc.En[1].Reg.Data.pcie.Fields.Reg == R_LPC_CFG_BC) &&
+             (Record->SrcDesc.En[1].Bit == N_LPC_CFG_BC_LE)) {
+    //
+    // eSPI/LPC Write Protect cannot be disabled
+    //
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = PchSmmCoreUnRegister (NULL, DispatchHandle);
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileUnregisterHandler (&gPchTcoSmiDispatchProtocolGuid, Record->Callback, NULL, 0);
+  }
+  return Status;
+}
+
+
+//
+// PcieRpHotPlug srcdesc
+//
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_SMM_SOURCE_DESC PchPcieSmiRpHotPlugTemplate = {
+  PCH_SMM_NO_FLAGS,
+  {
+    {
+      {
+        PCIE_ADDR_TYPE,
+        {R_PCH_PCIE_CFG_MPC}
+      },
+      S_PCH_PCIE_CFG_MPC,
+      N_PCH_PCIE_CFG_MPC_HPME
+    },
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        PCIE_ADDR_TYPE,
+        {R_PCH_PCIE_CFG_SMSCS}
+      },
+      S_PCH_PCIE_CFG_SMSCS,
+      N_PCH_PCIE_CFG_SMSCS_HPPDM
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_PCI_EXP
+  }
+};
+
+/**
+  The register function used to register SMI handler of PCIE RP hotplug event.
+
+  @param[in]  This                      The pointer to the protocol itself
+  @param[in]  DispatchFunction          Pointer to dispatch function to be invoked for this SMI source
+  @param[in]  RpIndex                   Refer PCIE_COMBINED_RPINDEX for PCH RP index and CPU RP index.
+  @param[out] DispatchHandle            Handle of dispatch function to register.
+
+  @retval EFI_INVALID_PARAMETER         Error with NULL SMI source description
+  @retval EFI_OUT_OF_RESOURCES          Fail to allocate pool for database record
+  @retval EFI_SUCCESS                   The database record is created successfully.
+  @retval EFI_ACCESS_DENIED             Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+PchPcieSmiHotPlugRegister (
+  IN  PCH_PCIE_SMI_DISPATCH_PROTOCOL    *This,
+  IN  PCH_PCIE_SMI_RP_DISPATCH_CALLBACK DispatchFunction,
+  IN  UINTN                             RpIndex,
+  OUT EFI_HANDLE                        *DispatchHandle
+  )
+{
+  EFI_STATUS                            Status;
+  UINTN                                 RpDev;
+  UINTN                                 RpFun;
+  PCH_SMM_PCIE_REGISTER_CONTEXT         Context;
+  DATABASE_RECORD                       *Record;
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+  GetPcieRpDevFun (RpIndex, &RpDev, &RpFun);
+
+  PchPcieSmiRpHotPlugTemplate.En[0].Reg.Data.pcie.Fields.Dev = (UINT8) RpDev;
+  PchPcieSmiRpHotPlugTemplate.En[0].Reg.Data.pcie.Fields.Fnc = (UINT8) RpFun;
+  PchPcieSmiRpHotPlugTemplate.Sts[0].Reg.Data.pcie.Fields.Dev = (UINT8) RpDev;
+  PchPcieSmiRpHotPlugTemplate.Sts[0].Reg.Data.pcie.Fields.Fnc = (UINT8) RpFun;
+
+  Status = PchSmiRecordInsert (
+             &PchPcieSmiRpHotPlugTemplate,
+             (PCH_SMI_CALLBACK_FUNCTIONS) DispatchFunction,
+             PchPcieSmiRpHotplugType,
+             DispatchHandle
+             );
+  if (!EFI_ERROR (Status)) {
+    Record = DATABASE_RECORD_FROM_LINK (*DispatchHandle);
+    Record->ChildContext.Pcie.PchSmiType = PchPcieSmiRpHotplugType;
+    Record->ChildContext.Pcie.RpIndex = RpIndex;
+    Record->ContextSize = sizeof (PCH_SMM_PCIE_REGISTER_CONTEXT);
+    SmiHandlerProfileRegisterHandler (
+      &gPchPcieSmiDispatchProtocolGuid,
+      (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction,
+      (UINTN)RETURN_ADDRESS (0),
+      &Context,
+      sizeof (Context)
+      );
+  }
+  PchSmmClearSource (&PchPcieSmiRpHotPlugTemplate);
+  PchSmmEnableSource (&PchPcieSmiRpHotPlugTemplate);
+
+  return Status;
+}
+
+//
+// PcieRpLinkActive srcdesc
+//
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_SMM_SOURCE_DESC PchPcieSmiRpLinkActiveTemplate = {
+  PCH_SMM_NO_FLAGS,
+  {
+    {
+      {
+        PCIE_ADDR_TYPE,
+        {R_PCH_PCIE_CFG_MPC}
+      },
+      S_PCH_PCIE_CFG_MPC,
+      N_PCH_PCIE_CFG_MPC_HPME
+    },
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        PCIE_ADDR_TYPE,
+        {R_PCH_PCIE_CFG_SMSCS}
+      },
+      S_PCH_PCIE_CFG_SMSCS,
+      N_PCH_PCIE_CFG_SMSCS_HPLAS
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_PCI_EXP
+  }
+};
+
+/**
+  The register function used to register SMI handler of PCIE RP link active event.
+
+  @param[in]  This                      The pointer to the protocol itself
+  @param[in]  DispatchFunction          Pointer to dispatch function to be invoked for this SMI source
+  @param[in]  RpIndex                   Refer PCIE_COMBINED_RPINDEX for PCH RP index and CPU RP index.
+  @param[out] DispatchHandle            Handle of dispatch function to register.
+
+  @retval EFI_INVALID_PARAMETER         Error with NULL SMI source description
+  @retval EFI_OUT_OF_RESOURCES          Fail to allocate pool for database record
+  @retval EFI_SUCCESS                   The database record is created successfully.
+  @retval EFI_ACCESS_DENIED             Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+PchPcieSmiLinkActiveRegister (
+  IN  PCH_PCIE_SMI_DISPATCH_PROTOCOL    *This,
+  IN  PCH_PCIE_SMI_RP_DISPATCH_CALLBACK DispatchFunction,
+  IN  UINTN                             RpIndex,
+  OUT EFI_HANDLE                        *DispatchHandle
+  )
+{
+  EFI_STATUS                            Status;
+  UINTN                                 RpDev;
+  UINTN                                 RpFun;
+  PCH_SMM_PCIE_REGISTER_CONTEXT         Context;
+  DATABASE_RECORD                       *Record;
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  GetPcieRpDevFun (RpIndex, &RpDev, &RpFun);
+
+
+  PchPcieSmiRpLinkActiveTemplate.En[0].Reg.Data.pcie.Fields.Dev = (UINT8) RpDev;
+  PchPcieSmiRpLinkActiveTemplate.En[0].Reg.Data.pcie.Fields.Fnc = (UINT8) RpFun;
+  PchPcieSmiRpLinkActiveTemplate.Sts[0].Reg.Data.pcie.Fields.Dev = (UINT8) RpDev;
+  PchPcieSmiRpLinkActiveTemplate.Sts[0].Reg.Data.pcie.Fields.Fnc = (UINT8) RpFun;
+
+  Status = PchSmiRecordInsert (
+             &PchPcieSmiRpLinkActiveTemplate,
+             (PCH_SMI_CALLBACK_FUNCTIONS) DispatchFunction,
+             PchPcieSmiRpLinkActiveType,
+             DispatchHandle
+             );
+  if (!EFI_ERROR (Status)) {
+    Record = DATABASE_RECORD_FROM_LINK (*DispatchHandle);
+    Record->ChildContext.Pcie.PchSmiType = PchPcieSmiRpLinkActiveType;
+    Record->ChildContext.Pcie.RpIndex = RpIndex;
+    Record->ContextSize = sizeof (PCH_SMM_PCIE_REGISTER_CONTEXT);
+    SmiHandlerProfileRegisterHandler (
+      &gPchPcieSmiDispatchProtocolGuid,
+      (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction,
+      (UINTN)RETURN_ADDRESS (0),
+      &Context,
+      sizeof (Context)
+      );
+  }
+  PchSmmClearSource (&PchPcieSmiRpLinkActiveTemplate);
+  PchSmmEnableSource (&PchPcieSmiRpLinkActiveTemplate);
+
+  return Status;
+}
+
+//
+// PcieRpLinkEq srcdesc
+//
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_SMM_SOURCE_DESC PchPcieSmiRpLinkEqTemplate = {
+  PCH_SMM_NO_FLAGS,
+  {
+    {
+      {
+        PCIE_ADDR_TYPE,
+        {R_PCH_PCIE_CFG_EQCFG1}
+      },
+      S_PCH_PCIE_CFG_EQCFG1,
+      N_PCH_PCIE_CFG_EQCFG1_LERSMIE
+    },
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        PCIE_ADDR_TYPE,
+        {R_PCH_PCIE_CFG_SMSCS}
+      },
+      S_PCH_PCIE_CFG_SMSCS,
+      N_PCH_PCIE_CFG_SMSCS_LERSMIS
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_PCI_EXP
+  }
+};
+/**
+  The register function used to register SMI handler of PCIE RP Link Equalization Request event.
+
+  @param[in]  This                      The pointer to the protocol itself
+  @param[in]  DispatchFunction          Pointer to dispatch function to be invoked for this SMI source
+  @param[in]  RpIndex                   Refer PCIE_COMBINED_RPINDEX for PCH RP index and CPU RP index.
+  @param[out] DispatchHandle            Handle of dispatch function to register.
+
+  @retval EFI_INVALID_PARAMETER         Error with NULL SMI source description
+  @retval EFI_OUT_OF_RESOURCES          Fail to allocate pool for database record
+  @retval EFI_SUCCESS                   The database record is created successfully.
+  @retval EFI_ACCESS_DENIED             Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+PchPcieSmiLinkEqRegister (
+  IN  PCH_PCIE_SMI_DISPATCH_PROTOCOL    *This,
+  IN  PCH_PCIE_SMI_RP_DISPATCH_CALLBACK DispatchFunction,
+  IN  UINTN                             RpIndex,
+  OUT EFI_HANDLE                        *DispatchHandle
+  )
+{
+  UINTN                                 RpDev;
+  UINTN                                 RpFun;
+  EFI_STATUS                            Status;
+  PCH_SMM_PCIE_REGISTER_CONTEXT         Context;
+  DATABASE_RECORD                       *Record;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  GetPcieRpDevFun (RpIndex, &RpDev, &RpFun);
+
+  //
+  // Patch the RP device number and function number of srcdesc.
+  //
+  PchPcieSmiRpLinkEqTemplate.En[0].Reg.Data.pcie.Fields.Dev = (UINT8) RpDev;
+  PchPcieSmiRpLinkEqTemplate.En[0].Reg.Data.pcie.Fields.Fnc = (UINT8) RpFun;
+  PchPcieSmiRpLinkEqTemplate.Sts[0].Reg.Data.pcie.Fields.Dev = (UINT8) RpDev;
+  PchPcieSmiRpLinkEqTemplate.Sts[0].Reg.Data.pcie.Fields.Fnc = (UINT8) RpFun;
+
+  Status = PchSmiRecordInsert (
+           &PchPcieSmiRpLinkEqTemplate,
+           (PCH_SMI_CALLBACK_FUNCTIONS) DispatchFunction,
+           PchPcieSmiRpLinkEqType,
+           DispatchHandle
+           );
+  if (!EFI_ERROR (Status)) {
+    Record = DATABASE_RECORD_FROM_LINK (*DispatchHandle);
+    Record->ChildContext.Pcie.PchSmiType = PchPcieSmiRpLinkEqType;
+    Record->ChildContext.Pcie.RpIndex = RpIndex;
+    Record->ContextSize = sizeof (PCH_SMM_PCIE_REGISTER_CONTEXT);
+    SmiHandlerProfileRegisterHandler (
+      &gPchPcieSmiDispatchProtocolGuid,
+      (EFI_SMM_HANDLER_ENTRY_POINT2) DispatchFunction,
+      (UINTN)RETURN_ADDRESS (0),
+      &Context,
+      sizeof (Context)
+      );
+  }
+  return Status;
+}
+
+/**
+  Unregister a child SMI source dispatch function with a parent SMM driver
+
+  @param[in] This                       Protocol instance pointer.
+  @param[in] DispatchHandle             Handle of dispatch function to deregister.
+
+  @retval EFI_SUCCESS                   The dispatch function has been successfully
+                                        unregistered and the SMI source has been disabled
+                                        if there are no other registered child dispatch
+                                        functions for this SMI source.
+  @retval EFI_INVALID_PARAMETER         Handle is invalid.
+  @retval EFI_ACCESS_DENIED             Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+PchPcieSmiUnRegister (
+  IN  PCH_PCIE_SMI_DISPATCH_PROTOCOL    *This,
+  IN  EFI_HANDLE                        DispatchHandle
+  )
+{
+  DATABASE_RECORD                       *RecordToDelete;
+  EFI_STATUS                            Status;
+
+  RecordToDelete = DATABASE_RECORD_FROM_LINK (DispatchHandle);
+  Status = PchSmmCoreUnRegister (NULL, DispatchHandle);
+  if (!EFI_ERROR (Status)) {
+      SmiHandlerProfileUnregisterHandler (
+        &gPchPcieSmiDispatchProtocolGuid,
+        RecordToDelete->Callback,
+        &RecordToDelete->ChildContext,
+        sizeof (RecordToDelete->ContextSize)
+        );
+  }
+  return Status;
+}
+
+//
+// Pme srcdesc
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mSrcDescPme = {
+  PCH_SMM_SCI_EN_DEPENDENT,
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_GPE0_EN_127_96}
+      },
+      S_ACPI_IO_GPE0_EN_127_96,
+      N_ACPI_IO_GPE0_EN_127_96_PME
+    },
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_GPE0_STS_127_96}
+      },
+      S_ACPI_IO_GPE0_STS_127_96,
+      N_ACPI_IO_GPE0_STS_127_96_PME
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_GPE0
+  }
+};
+
+/**
+  The register function used to register SMI handler of PME event.
+
+  @param[in]  This                      The pointer to the protocol itself
+  @param[in]  DispatchFunction          Pointer to dispatch function to be invoked for this SMI source
+  @param[out] DispatchHandle            Handle of dispatch function to register.
+
+  @retval EFI_INVALID_PARAMETER         Error with NULL SMI source description
+  @retval EFI_OUT_OF_RESOURCES          Fail to allocate pool for database record
+  @retval EFI_SUCCESS                   The database record is created successfully.
+  @retval EFI_ACCESS_DENIED             Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+PchAcpiSmiPmeRegister (
+  IN  PCH_ACPI_SMI_DISPATCH_PROTOCOL    *This,
+  IN  PCH_ACPI_SMI_DISPATCH_CALLBACK    DispatchFunction,
+  OUT EFI_HANDLE                        *DispatchHandle
+  )
+{
+  EFI_STATUS                            Status;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = PchSmiRecordInsert (
+             &mSrcDescPme,
+             (PCH_SMI_CALLBACK_FUNCTIONS) DispatchFunction,
+             PchAcpiSmiPmeType,
+             DispatchHandle
+             );
+  PchSmmClearSource (&mSrcDescPme);
+  PchSmmEnableSource (&mSrcDescPme);
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileRegisterHandler (&gPchAcpiSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  return Status;
+}
+
+//
+// PmeB0 srcdesc
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mSrcDescPmeB0 = {
+  PCH_SMM_SCI_EN_DEPENDENT,
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_GPE0_EN_127_96}
+      },
+      S_ACPI_IO_GPE0_EN_127_96,
+      N_ACPI_IO_GPE0_EN_127_96_PME_B0
+    },
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_GPE0_STS_127_96}
+      },
+      S_ACPI_IO_GPE0_STS_127_96,
+      N_ACPI_IO_GPE0_STS_127_96_PME_B0
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_GPE0
+  }
+};
+/**
+  The register function used to register SMI handler of PME B0 event.
+
+  @param[in]  This                      The pointer to the protocol itself
+  @param[in]  DispatchFunction          Pointer to dispatch function to be invoked for this SMI source
+  @param[out] DispatchHandle            Handle of dispatch function to register.
+
+  @retval EFI_INVALID_PARAMETER         Error with NULL SMI source description
+  @retval EFI_OUT_OF_RESOURCES          Fail to allocate pool for database record
+  @retval EFI_SUCCESS                   The database record is created successfully.
+  @retval EFI_ACCESS_DENIED             Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+PchAcpiSmiPmeB0Register (
+  IN  PCH_ACPI_SMI_DISPATCH_PROTOCOL    *This,
+  IN  PCH_ACPI_SMI_DISPATCH_CALLBACK    DispatchFunction,
+  OUT EFI_HANDLE                        *DispatchHandle
+  )
+{
+  EFI_STATUS                            Status;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = PchSmiRecordInsert (
+             &mSrcDescPmeB0,
+             (PCH_SMI_CALLBACK_FUNCTIONS) DispatchFunction,
+             PchAcpiSmiPmeB0Type,
+             DispatchHandle
+             );
+  PchSmmClearSource (&mSrcDescPmeB0);
+  PchSmmEnableSource (&mSrcDescPmeB0);
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileRegisterHandler (&gPchAcpiSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  return Status;
+}
+
+//
+// RtcAlarm srcdesc
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mSrcDescRtcAlarm = {
+  PCH_SMM_SCI_EN_DEPENDENT,
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_PM1_EN}
+      },
+      S_ACPI_IO_PM1_EN,
+      N_ACPI_IO_PM1_EN_RTC
+    },
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_PM1_STS}
+      },
+      S_ACPI_IO_PM1_STS,
+      N_ACPI_IO_PM1_STS_RTC
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_PM1_STS_REG
+  }
+};
+
+/**
+  The register function used to register SMI handler of RTC alarm event.
+
+  @param[in]  This                      The pointer to the protocol itself
+  @param[in]  DispatchFunction          Pointer to dispatch function to be invoked for this SMI source
+  @param[out] DispatchHandle            Handle of dispatch function to register.
+
+  @retval EFI_INVALID_PARAMETER         Error with NULL SMI source description
+  @retval EFI_OUT_OF_RESOURCES          Fail to allocate pool for database record
+  @retval EFI_SUCCESS                   The database record is created successfully.
+  @retval EFI_ACCESS_DENIED             Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+PchAcpiSmiRtcAlarmRegister (
+  IN  PCH_ACPI_SMI_DISPATCH_PROTOCOL    *This,
+  IN  PCH_ACPI_SMI_DISPATCH_CALLBACK    DispatchFunction,
+  OUT EFI_HANDLE                        *DispatchHandle
+  )
+{
+  EFI_STATUS                            Status;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = PchSmiRecordInsert (
+             &mSrcDescRtcAlarm,
+             (PCH_SMI_CALLBACK_FUNCTIONS) DispatchFunction,
+             PchAcpiSmiRtcAlarmType,
+             DispatchHandle
+             );
+
+  PchSmmClearSource (&mSrcDescRtcAlarm);
+  PchSmmEnableSource (&mSrcDescRtcAlarm);
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileRegisterHandler (&gPchAcpiSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  return Status;
+}
+
+//
+// TmrOverflow srcdesc
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mSrcDescTmrOverflow = {
+  PCH_SMM_SCI_EN_DEPENDENT,
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_PM1_EN}
+      },
+      S_ACPI_IO_PM1_EN,
+      N_ACPI_IO_PM1_EN_TMROF
+    },
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_PM1_STS}
+      },
+      S_ACPI_IO_PM1_STS,
+      N_ACPI_IO_PM1_STS_TMROF
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_PM1_STS_REG
+  }
+};
+
+/**
+  The register function used to register SMI handler of Timer Overflow event.
+
+  @param[in]  This                      The pointer to the protocol itself
+  @param[in]  DispatchFunction          Pointer to dispatch function to be invoked for this SMI source
+  @param[out] DispatchHandle            Handle of dispatch function to register.
+
+  @retval EFI_INVALID_PARAMETER         Error with NULL SMI source description
+  @retval EFI_OUT_OF_RESOURCES          Fail to allocate pool for database record
+  @retval EFI_SUCCESS                   The database record is created successfully.
+  @retval EFI_ACCESS_DENIED             Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+PchAcpiSmiTmrOverflowRegister (
+  IN  PCH_ACPI_SMI_DISPATCH_PROTOCOL    *This,
+  IN  PCH_ACPI_SMI_DISPATCH_CALLBACK    DispatchFunction,
+  OUT EFI_HANDLE                        *DispatchHandle
+  )
+{
+  EFI_STATUS                            Status;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = PchSmiRecordInsert (
+             &mSrcDescTmrOverflow,
+             (PCH_SMI_CALLBACK_FUNCTIONS) DispatchFunction,
+             PchAcpiSmiTmrOverflowType,
+             DispatchHandle
+             );
+  PchSmmClearSource (&mSrcDescTmrOverflow);
+  PchSmmEnableSource (&mSrcDescTmrOverflow);
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileRegisterHandler (&gPchAcpiSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+
+  return Status;
+}
+
+/**
+  Unregister a child SMI source dispatch function with a parent SMM driver
+
+  @param[in] This                       Protocol instance pointer.
+  @param[in] DispatchHandle             Handle of dispatch function to deregister.
+
+  @retval EFI_SUCCESS                   The dispatch function has been successfully
+                                        unregistered and the SMI source has been disabled
+                                        if there are no other registered child dispatch
+                                        functions for this SMI source.
+  @retval EFI_INVALID_PARAMETER         Handle is invalid.
+  @retval EFI_ACCESS_DENIED             Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+PchAcpiSmiUnRegister (
+  IN  PCH_ACPI_SMI_DISPATCH_PROTOCOL    *This,
+  IN  EFI_HANDLE                        DispatchHandle
+  )
+{
+  DATABASE_RECORD                   *RecordToDelete;
+  EFI_STATUS                        Status;
+
+  RecordToDelete = DATABASE_RECORD_FROM_LINK (DispatchHandle);
+  Status = PchSmmCoreUnRegister (NULL, DispatchHandle);
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileUnregisterHandler (&gPchAcpiSmiDispatchProtocolGuid, RecordToDelete->Callback, NULL, 0);
+  }
+  return Status;
+}
+
+//
+// SerialIrq srcdesc
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mSrcDescSerialIrq = {
+  PCH_SMM_NO_FLAGS,
+  {
+    NULL_BIT_DESC_INITIALIZER,
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_STS}
+      },
+      S_ACPI_IO_SMI_STS,
+      N_ACPI_IO_SMI_STS_SERIRQ
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_SERIRQ
+  }
+};
+
+/**
+  The register function used to register SMI handler of Serial IRQ event.
+
+  @param[in]  This                      The pointer to the protocol itself
+  @param[in]  DispatchFunction          Pointer to dispatch function to be invoked for this SMI source
+  @param[out] DispatchHandle            Handle of dispatch function to register.
+
+  @retval EFI_INVALID_PARAMETER         Error with NULL SMI source description
+  @retval EFI_OUT_OF_RESOURCES          Fail to allocate pool for database record
+  @retval EFI_SUCCESS                   The database record is created successfully.
+  @retval EFI_ACCESS_DENIED             Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+PchSmiSerialIrqRegister (
+  IN  PCH_SMI_DISPATCH_PROTOCOL         *This,
+  IN  PCH_SMI_DISPATCH_CALLBACK         DispatchFunction,
+  OUT EFI_HANDLE                        *DispatchHandle
+  )
+{
+  EFI_STATUS                            Status;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = PchSmiRecordInsert (
+             &mSrcDescSerialIrq,
+             (PCH_SMI_CALLBACK_FUNCTIONS) DispatchFunction,
+             PchSmiSerialIrqType,
+             DispatchHandle
+             );
+  PchSmmClearSource (&mSrcDescSerialIrq);
+  PchSmmEnableSource (&mSrcDescSerialIrq);
+  if (!EFI_ERROR (Status)) {
+     SmiHandlerProfileRegisterHandler (&gPchSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  return Status;
+}
+
+//
+// McSmi srcdesc
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mSrcDescMcSmi = {
+  PCH_SMM_NO_FLAGS,
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_EN}
+      },
+      S_ACPI_IO_SMI_EN,
+      N_ACPI_IO_SMI_EN_MCSMI
+    },
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_STS}
+      },
+      S_ACPI_IO_SMI_STS,
+      N_ACPI_IO_SMI_STS_MCSMI
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_MCSMI
+  }
+};
+
+/**
+  The register function used to register SMI handler of MCSMI event.
+
+  @param[in]  This                      The pointer to the protocol itself
+  @param[in]  DispatchFunction          Pointer to dispatch function to be invoked for this SMI source
+  @param[out] DispatchHandle            Handle of dispatch function to register.
+
+  @retval EFI_INVALID_PARAMETER         Error with NULL SMI source description
+  @retval EFI_OUT_OF_RESOURCES          Fail to allocate pool for database record
+  @retval EFI_SUCCESS                   The database record is created successfully.
+  @retval EFI_ACCESS_DENIED             Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+PchSmiMcSmiRegister (
+  IN  PCH_SMI_DISPATCH_PROTOCOL         *This,
+  IN  PCH_SMI_DISPATCH_CALLBACK         DispatchFunction,
+  OUT EFI_HANDLE                        *DispatchHandle
+  )
+{
+  EFI_STATUS                            Status;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = PchSmiRecordInsert (
+             &mSrcDescMcSmi,
+             (PCH_SMI_CALLBACK_FUNCTIONS) DispatchFunction,
+             PchSmiMcSmiType,
+             DispatchHandle
+             );
+  PchSmmClearSource (&mSrcDescMcSmi);
+  PchSmmEnableSource (&mSrcDescMcSmi);
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileRegisterHandler (&gPchSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  return Status;
+}
+
+//
+// SmBus srcdesc
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mSrcDescSmbus = {
+  PCH_SMM_NO_FLAGS,
+  {
+    NULL_BIT_DESC_INITIALIZER,
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_STS}
+      },
+      S_ACPI_IO_SMI_STS,
+      N_ACPI_IO_SMI_STS_SMBUS
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_SMBUS
+  }
+};
+
+/**
+  The register function used to register SMI handler of SMBUS event.
+
+  @param[in]  This                      The pointer to the protocol itself
+  @param[in]  DispatchFunction          Pointer to dispatch function to be invoked for this SMI source
+  @param[out] DispatchHandle            Handle of dispatch function to register.
+
+  @retval EFI_INVALID_PARAMETER         Error with NULL SMI source description
+  @retval EFI_OUT_OF_RESOURCES          Fail to allocate pool for database record
+  @retval EFI_SUCCESS                   The database record is created successfully.
+  @retval EFI_ACCESS_DENIED             Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+PchSmiSmbusRegister (
+  IN  PCH_SMI_DISPATCH_PROTOCOL         *This,
+  IN  PCH_SMI_DISPATCH_CALLBACK         DispatchFunction,
+  OUT EFI_HANDLE                        *DispatchHandle
+  )
+{
+  EFI_STATUS                            Status;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = PchSmiRecordInsert (
+             &mSrcDescSmbus,
+             (PCH_SMI_CALLBACK_FUNCTIONS) DispatchFunction,
+             PchSmiSmBusType,
+             DispatchHandle
+             );
+  PchSmmClearSource (&mSrcDescSmbus);
+  PchSmmEnableSource (&mSrcDescSmbus);
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileRegisterHandler (&gPchSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  return Status;
+}
+
+//
+// SpiAsyncSmi srcdesc
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mSrcDescSpiAsyncSmi = {
+  PCH_SMM_NO_FLAGS,
+  {
+    {
+      {
+        PCIE_ADDR_TYPE,
+        { (
+          (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+          (PCI_DEVICE_NUMBER_PCH_SPI << 19) |
+          (PCI_FUNCTION_NUMBER_PCH_SPI << 16) |
+          R_SPI_CFG_BC
+        ) }
+      },
+      S_SPI_CFG_BC,
+      N_SPI_CFG_BC_ASE_BWP
+    },
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        PCIE_ADDR_TYPE,
+        { (
+          (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+          (PCI_DEVICE_NUMBER_PCH_SPI << 19) |
+          (PCI_FUNCTION_NUMBER_PCH_SPI << 16) |
+          R_SPI_CFG_BC
+        ) }
+      },
+      S_SPI_CFG_BC,
+      N_SPI_CFG_BC_ASYNC_SS
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_SPI
+  }
+};
+
+/**
+  Special handling for SPI Asynchronous SMI.
+  If SPI ASYNC SMI is enabled, De-assert SMI is sent when Flash Cycle Done
+  transitions from 1 to 0 or when the SMI enable becomes false.
+
+  @param[in]  SrcDesc   Not used
+**/
+VOID
+EFIAPI
+PchSmiSpiAsyncClearSource (
+  CONST PCH_SMM_SOURCE_DESC             *SrcDesc
+  )
+{
+  UINT64                                SpiRegBase;
+  UINT32                                SpiBar0;
+
+  SpiRegBase = SpiPciCfgBase ();
+  SpiBar0 = PciSegmentRead32 (SpiRegBase + R_SPI_CFG_BAR0) & ~(B_SPI_CFG_BAR0_MASK);
+  if (SpiBar0 != PCH_SPI_BASE_ADDRESS) {
+    //
+    // Temporary disable MSE, and override with SPI reserved MMIO address, then enable MSE.
+    //
+    SpiBar0 = PCH_SPI_BASE_ADDRESS;
+    PciSegmentAnd8 (SpiRegBase + PCI_COMMAND_OFFSET, (UINT8) ~EFI_PCI_COMMAND_MEMORY_SPACE);
+    PciSegmentWrite32 (SpiRegBase + R_SPI_CFG_BAR0, SpiBar0);
+    PciSegmentOr8 (SpiRegBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
+  }
+
+  MmioOr32 (SpiBar0 + R_SPI_MEM_HSFSC, B_SPI_MEM_HSFSC_FDONE);
+}
+
+/**
+  Special handling to enable SPI Asynchronous SMI
+**/
+VOID
+PchSmiSpiAsyncEnableSource (
+  VOID
+  )
+{
+  UINT64 SpiRegBase;
+  UINT32 Data32And;
+  UINT32 Data32Or;
+
+  SpiRegBase = SpiPciCfgBase ();
+  Data32And = (UINT32) ~B_SPI_CFG_BC_SYNC_SS;
+  Data32Or = B_SPI_CFG_BC_ASE_BWP;
+
+  PciSegmentAndThenOr32 (
+    SpiRegBase + R_SPI_CFG_BC,
+    Data32And,
+    Data32Or
+    );
+  S3BootScriptSavePciCfgReadWrite (
+    S3BootScriptWidthUint32,
+    SpiRegBase + R_SPI_CFG_BC,
+    (VOID*) &Data32Or,
+    (VOID*) &Data32And
+    );
+
+  //
+  // Clear the source
+  //
+  PchSmiSpiAsyncClearSource (NULL);
+}
+
+/**
+  The register function used to register SMI handler of SPI Asynchronous event.
+
+  @param[in]  This                      The pointer to the protocol itself
+  @param[in]  DispatchFunction          Pointer to dispatch function to be invoked for this SMI source
+  @param[out] DispatchHandle            Handle of dispatch function to register.
+
+  @retval EFI_INVALID_PARAMETER         Error with NULL SMI source description
+  @retval EFI_OUT_OF_RESOURCES          Fail to allocate pool for database record
+  @retval EFI_SUCCESS                   The database record is created successfully.
+  @retval EFI_ACCESS_DENIED             Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+PchSmiSpiAsyncRegister (
+  IN  PCH_SMI_DISPATCH_PROTOCOL         *This,
+  IN  PCH_SMI_DISPATCH_CALLBACK         DispatchFunction,
+  OUT EFI_HANDLE                        *DispatchHandle
+  )
+{
+  EFI_STATUS                            Status;
+  DATABASE_RECORD                       *Record;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = PchSmiRecordInsert (
+             &mSrcDescSpiAsyncSmi,
+             (PCH_SMI_CALLBACK_FUNCTIONS) DispatchFunction,
+             PchSmiSpiAsyncType,
+             DispatchHandle
+             );
+
+  if (!EFI_ERROR (Status)) {
+    Record = DATABASE_RECORD_FROM_LINK (*DispatchHandle);
+    Record->ClearSource = PchSmiSpiAsyncClearSource;
+    PchSmiSpiAsyncClearSource (NULL);
+    PchSmiSpiAsyncEnableSource ();
+    SmiHandlerProfileRegisterHandler (&gPchSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  return Status;
+}
+
+/**
+  Unregister a child SMI source dispatch function with a parent SMM driver
+
+  @param[in] This                       Protocol instance pointer.
+  @param[in] DispatchHandle             Handle of dispatch function to deregister.
+
+  @retval EFI_SUCCESS                   The dispatch function has been successfully
+                                        unregistered and the SMI source has been disabled
+                                        if there are no other registered child dispatch
+                                        functions for this SMI source.
+  @retval EFI_INVALID_PARAMETER         Handle is invalid.
+  @retval EFI_ACCESS_DENIED             Return access denied if the SmmReadyToLock event has been triggered
+  @retval EFI_ACCESS_DENIED             Return access denied since SPI aync SMI handler is not able to disabled.
+**/
+EFI_STATUS
+EFIAPI
+PchSmiUnRegister (
+  IN  PCH_SMI_DISPATCH_PROTOCOL         *This,
+  IN  EFI_HANDLE                        DispatchHandle
+  )
+{
+  DATABASE_RECORD                       *Record;
+  UINT64                                SpiRegBase;
+  EFI_STATUS                            Status;
+
+  Record = DATABASE_RECORD_FROM_LINK (DispatchHandle);
+  if ((Record->SrcDesc.En[0].Reg.Type == PCIE_ADDR_TYPE) &&
+      (Record->SrcDesc.En[0].Reg.Data.pcie.Fields.Dev == SpiDevNumber ()) &&
+      (Record->SrcDesc.En[0].Reg.Data.pcie.Fields.Fnc == SpiFuncNumber ()) &&
+      (Record->SrcDesc.En[0].Reg.Data.pcie.Fields.Reg == R_SPI_CFG_BC) &&
+      (Record->SrcDesc.En[0].Bit == N_SPI_CFG_BC_ASE_BWP)) {
+    SpiRegBase = SpiPciCfgBase ();
+    if (PciSegmentRead8 (SpiRegBase + R_SPI_CFG_BC) & B_SPI_CFG_BC_BILD) {
+      //
+      // SPI Asynchronous SMI cannot be disabled
+      //
+      return EFI_ACCESS_DENIED;
+    }
+  }
+  Status = PchSmmCoreUnRegister (NULL, DispatchHandle);
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileUnregisterHandler (&gPchSmiDispatchProtocolGuid, Record->Callback, NULL, 0);
+  }
+  return Status;
+}
+
+
+/**
+  Declaration of PCH TCO SMI DISPATCH PROTOCOL instance
+**/
+PCH_TCO_SMI_DISPATCH_PROTOCOL mPchTcoSmiDispatchProtocol = {
+  PCH_TCO_SMI_DISPATCH_REVISION,        // Revision
+  PchTcoSmiUnRegister,                  // Unregister
+  PchTcoSmiMchRegister,                 // Mch
+  PchTcoSmiTcoTimeoutRegister,          // TcoTimeout
+  PchTcoSmiOsTcoRegister,               // OsTco
+  PchTcoSmiNmiRegister,                 // Nmi
+  PchTcoSmiIntruderDetRegister,         // IntruderDectect
+  PchTcoSmiSpiBiosWpRegister,           // SpiBiosWp
+  PchTcoSmiLpcBiosWpRegister,           // LpcBiosWp
+  PchTcoSmiNewCenturyRegister           // NewCentury
+};
+
+/**
+  Declaration of PCH PCIE SMI DISPATCH PROTOCOL instance
+**/
+PCH_PCIE_SMI_DISPATCH_PROTOCOL mPchPcieSmiDispatchProtocol = {
+  PCH_PCIE_SMI_DISPATCH_REVISION,       // Revision
+  PchPcieSmiUnRegister,                 // Unregister
+  PchPcieSmiHotPlugRegister,            // PcieRpXHotPlug
+  PchPcieSmiLinkActiveRegister,         // PcieRpXLinkActive
+  PchPcieSmiLinkEqRegister              // PcieRpXLinkEq
+};
+
+/**
+  Declaration of PCH ACPI SMI DISPATCH PROTOCOL instance
+**/
+PCH_ACPI_SMI_DISPATCH_PROTOCOL mPchAcpiSmiDispatchProtocol = {
+  PCH_ACPI_SMI_DISPATCH_REVISION,       // Revision
+  PchAcpiSmiUnRegister,                 // Unregister
+  PchAcpiSmiPmeRegister,                // Pme
+  PchAcpiSmiPmeB0Register,              // PmeB0
+  PchAcpiSmiRtcAlarmRegister,           // RtcAlarm
+  PchAcpiSmiTmrOverflowRegister         // TmrOverflow
+};
+
+/**
+  Declaration of MISC PCH SMI DISPATCH PROTOCOL instance
+**/
+PCH_SMI_DISPATCH_PROTOCOL mPchSmiDispatchProtocol = {
+  PCH_SMI_DISPATCH_REVISION,            // Revision
+  PchSmiUnRegister,                     // Unregister
+  PchSmiSerialIrqRegister,              // SerialIrq
+  PchSmiMcSmiRegister,                  // McSmi
+  PchSmiSmbusRegister,                  // SmBus
+  PchSmiSpiAsyncRegister                // SpiAsync
+};
+
+/**
+  Install protocols of PCH specifics SMI types, including
+  PCH TCO SMI types, PCH PCIE SMI types, PCH ACPI SMI types, PCH MISC SMI types.
+
+  @retval                               the result of protocol installation
+**/
+EFI_STATUS
+InstallPchSmiDispatchProtocols (
+  VOID
+  )
+{
+  EFI_HANDLE                            Handle;
+  EFI_STATUS                            Status;
+
+  Handle = NULL;
+  Status = gSmst->SmmInstallProtocolInterface (
+                    &Handle,
+                    &gPchTcoSmiDispatchProtocolGuid,
+                    EFI_NATIVE_INTERFACE,
+                    &mPchTcoSmiDispatchProtocol
+                    );
+  Status = gSmst->SmmInstallProtocolInterface (
+                    &Handle,
+                    &gPchPcieSmiDispatchProtocolGuid,
+                    EFI_NATIVE_INTERFACE,
+                    &mPchPcieSmiDispatchProtocol
+                    );
+  Status = gSmst->SmmInstallProtocolInterface (
+                    &Handle,
+                    &gPchAcpiSmiDispatchProtocolGuid,
+                    EFI_NATIVE_INTERFACE,
+                    &mPchAcpiSmiDispatchProtocol
+                    );
+  Status = gSmst->SmmInstallProtocolInterface (
+                    &Handle,
+                    &gPchSmiDispatchProtocolGuid,
+                    EFI_NATIVE_INTERFACE,
+                    &mPchSmiDispatchProtocol
+                    );
+
+  return Status;
+}
+
+/**
+  The function to dispatch all callback function of PCH SMI types.
+
+  @retval EFI_SUCCESS                   Function successfully completed
+  @retval EFI_UNSUPPORTED               no
+**/
+EFI_STATUS
+PchSmiTypeCallbackDispatcher (
+  IN  DATABASE_RECORD                   *Record
+  )
+{
+  EFI_STATUS                            Status;
+  PCH_SMI_TYPES                         PchSmiType;
+  UINTN                                 RpIndex;
+  PCH_PCIE_SMI_RP_CONTEXT               RpContext;
+
+  PchSmiType = Record->PchSmiType;
+  Status     = EFI_SUCCESS;
+
+  switch (PchSmiType) {
+    case PchTcoSmiMchType:
+    case PchTcoSmiTcoTimeoutType:
+    case PchTcoSmiOsTcoType:
+    case PchTcoSmiNmiType:
+    case PchTcoSmiIntruderDetectType:
+    case PchTcoSmiSpiBiosWpType:
+    case PchTcoSmiLpcBiosWpType:
+    case PchTcoSmiNewCenturyType:
+      ((PCH_TCO_SMI_DISPATCH_CALLBACK) (Record->PchSmiCallback)) ((EFI_HANDLE)&Record->Link);
+      break;
+    case PchPcieSmiRpHotplugType:
+    case PchPcieSmiRpLinkActiveType:
+    case PchPcieSmiRpLinkEqType:
+      RpContext.BusNum  = DEFAULT_PCI_BUS_NUMBER_PCH;
+      RpContext.DevNum  = (UINT8) Record->SrcDesc.En[0].Reg.Data.pcie.Fields.Dev;
+      RpContext.FuncNum = (UINT8) Record->SrcDesc.En[0].Reg.Data.pcie.Fields.Fnc;
+      GetPcieRpNumber (RpContext.DevNum, RpContext.FuncNum, &RpIndex);
+      RpContext.RpIndex = (UINT8) RpIndex;
+      ((PCH_PCIE_SMI_RP_DISPATCH_CALLBACK) (Record->PchSmiCallback)) ((EFI_HANDLE)&Record->Link, &RpContext);
+      break;
+    case PchAcpiSmiPmeType:
+    case PchAcpiSmiPmeB0Type:
+    case PchAcpiSmiRtcAlarmType:
+    case PchAcpiSmiTmrOverflowType:
+      ((PCH_ACPI_SMI_DISPATCH_CALLBACK) (Record->PchSmiCallback)) ((EFI_HANDLE)&Record->Link);
+      break;
+    case PchEspiSmiEspiSlaveType:
+      ((PCH_ESPI_SMI_DISPATCH_CALLBACK) (Record->PchSmiCallback)) ((EFI_HANDLE)&Record->Link);
+      break;
+    case PchSmiSerialIrqType:
+    case PchSmiMcSmiType:
+    case PchSmiSmBusType:
+    case PchSmiSpiAsyncType:
+    case PchIoTrapSmiType:                ///< internal type for IoTrap
+      ((PCH_SMI_DISPATCH_CALLBACK) (Record->PchSmiCallback)) ((EFI_HANDLE)&Record->Link);
+      break;
+    default:
+      Status = EFI_UNSUPPORTED;
+      break;
+  }
+
+  return Status;
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mSrcDescIoTrap[4] = {
+  //
+  // PCH I/O Trap register 0 monitor
+  //
+  {
+    PCH_SMM_NO_FLAGS,
+    {
+      {
+        {
+          PCR_ADDR_TYPE,
+          {PCH_PCR_ADDRESS (PID_PSTH, R_PSTH_PCR_TRPREG0) }
+        },
+        4,
+        0
+      },
+      NULL_BIT_DESC_INITIALIZER
+    },
+    {
+      {
+        {
+          PCR_ADDR_TYPE,
+          {PCH_PCR_ADDRESS (PID_PSTH, R_PSTH_PCR_TRPST) }
+        },
+        1,
+        0
+      }
+    },
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_STS}
+      },
+      S_ACPI_IO_SMI_STS,
+      N_ACPI_IO_SMI_STS_MONITOR
+    }
+  },
+  //
+  // PCH I/O Trap register 1 monitor
+  //
+  {
+    PCH_SMM_NO_FLAGS,
+    {
+      {
+        {
+          PCR_ADDR_TYPE,
+          {PCH_PCR_ADDRESS (PID_PSTH, R_PSTH_PCR_TRPREG1) }
+        },
+        4,
+        0
+      },
+      NULL_BIT_DESC_INITIALIZER
+    },
+    {
+      {
+        {
+          PCR_ADDR_TYPE,
+          {PCH_PCR_ADDRESS (PID_PSTH, R_PSTH_PCR_TRPST) }
+        },
+        1,
+        1
+      }
+    },
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_STS}
+      },
+      S_ACPI_IO_SMI_STS,
+      N_ACPI_IO_SMI_STS_MONITOR
+    }
+  },
+  //
+  // PCH I/O Trap register 2 monitor
+  //
+  {
+    PCH_SMM_NO_FLAGS,
+    {
+      {
+        {
+          PCR_ADDR_TYPE,
+          {PCH_PCR_ADDRESS (PID_PSTH, R_PSTH_PCR_TRPREG2) }
+        },
+        4,
+        0
+      },
+      NULL_BIT_DESC_INITIALIZER
+    },
+    {
+      {
+        {
+          PCR_ADDR_TYPE,
+          {PCH_PCR_ADDRESS (PID_PSTH, R_PSTH_PCR_TRPST) }
+        },
+        1,
+        2
+      }
+    },
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_STS}
+      },
+      S_ACPI_IO_SMI_STS,
+      N_ACPI_IO_SMI_STS_MONITOR
+    }
+  },
+  //
+  // PCH I/O Trap register 3 monitor,
+  //
+  {
+    PCH_SMM_NO_FLAGS,
+    {
+      {
+        {
+          PCR_ADDR_TYPE,
+          {PCH_PCR_ADDRESS (PID_PSTH, R_PSTH_PCR_TRPREG3) }
+        },
+        4,
+        0
+      },
+      NULL_BIT_DESC_INITIALIZER
+    },
+    {
+      {
+        {
+          PCR_ADDR_TYPE,
+          {PCH_PCR_ADDRESS (PID_PSTH, R_PSTH_PCR_TRPST) }
+        },
+        1,
+        3
+      }
+    },
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_STS}
+      },
+      S_ACPI_IO_SMI_STS,
+      N_ACPI_IO_SMI_STS_MONITOR
+    }
+  }
+};
+
+/**
+  The register function used to register SMI handler of IoTrap event.
+  This is internal function and only used by Iotrap module.
+
+  @param[in]  DispatchFunction          Pointer to dispatch function to be invoked for this SMI source
+  @param[in]  IoTrapIndex               Index number of IOTRAP register
+  @param[out] DispatchHandle            Handle of dispatch function to register.
+
+  @retval EFI_INVALID_PARAMETER         Error with NULL SMI source description
+  @retval EFI_OUT_OF_RESOURCES          Fail to allocate pool for database record
+  @retval EFI_SUCCESS                   The database record is created successfully.
+**/
+EFI_STATUS
+PchInternalIoTrapSmiRegister (
+  IN  PCH_SMI_DISPATCH_CALLBACK         DispatchFunction,
+  IN  UINTN                             IoTrapIndex,
+  OUT EFI_HANDLE                        *DispatchHandle
+  )
+{
+  EFI_STATUS                            Status;
+
+  Status = PchSmiRecordInsert (
+             &mSrcDescIoTrap[IoTrapIndex],
+             (PCH_SMI_CALLBACK_FUNCTIONS) DispatchFunction,
+             PchIoTrapSmiType,
+             DispatchHandle
+             );
+  PchSmmClearSource (&mSrcDescIoTrap[IoTrapIndex]);
+  PchSmmEnableSource (&mSrcDescIoTrap[IoTrapIndex]);
+  return Status;
+}
+
+/**
+  Unregister a child SMI source dispatch function with a parent SMM driver
+
+  @param[in] DispatchHandle             Handle of dispatch function to deregister.
+
+  @retval EFI_SUCCESS                   The dispatch function has been successfully
+                                        unregistered and the SMI source has been disabled
+                                        if there are no other registered child dispatch
+                                        functions for this SMI source.
+  @retval EFI_INVALID_PARAMETER         Handle is invalid.
+**/
+EFI_STATUS
+PchInternalIoTrapSmiUnRegister (
+  IN  EFI_HANDLE                        DispatchHandle
+  )
+{
+  return PchSmmCoreUnRegister (NULL, DispatchHandle);
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatcher.inf b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatcher.inf
new file mode 100644
index 0000000000..97ad2f457e
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiDispatcher.inf
@@ -0,0 +1,116 @@
+## @file
+# Component description file for the Pch SMI Dispatch Handlers module
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PchSmiDispatcher
+FILE_GUID = B0D6ED53-B844-43f5-BD2F-61095264E77E
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_SMM_DRIVER
+PI_SPECIFICATION_VERSION = 1.10
+ENTRY_POINT = InitializePchSmmDispatcher
+
+
+[LibraryClasses]
+UefiBootServicesTableLib
+UefiDriverEntryPoint
+IoLib
+DebugLib
+PcdLib
+BaseLib
+BaseMemoryLib
+HobLib
+DevicePathLib
+PchCycleDecodingLib
+PchPcieRpLib
+PchPcrLib
+SmmServicesTableLib
+ReportStatusCodeLib
+PerformanceLib
+DxeServicesTableLib
+GpioLib
+GpioPrivateLib
+EspiLib
+S3BootScriptLib
+ConfigBlockLib
+PmcPrivateLib
+PmcLib
+SmiHandlerProfileLib
+CpuPcieRpLib
+PchPciBdfLib
+PmcPrivateLibWithS3
+CpuPcieInfoFruLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+# Progress Code for S3 Suspend start.
+# PROGRESS_CODE_S3_SUSPEND_START = (EFI_SOFTWARE_SMM_DRIVER | (EFI_OEM_SPECIFIC | 0x00000000))    = 0x03078000
+gSiPkgTokenSpaceGuid.PcdProgressCodeS3SuspendStart
+# Progress Code for S3 Suspend end.
+# PROGRESS_CODE_S3_SUSPEND_END   = (EFI_SOFTWARE_SMM_DRIVER | (EFI_OEM_SPECIFIC | 0x00000001))    = 0x03078001
+gSiPkgTokenSpaceGuid.PcdProgressCodeS3SuspendEnd
+gSiPkgTokenSpaceGuid.PcdEfiGcdAllocateType
+
+
+[Sources]
+PchSmm.h
+PchSmmCore.c
+PchSmmHelpers.h
+PchSmmHelpers.c
+PchxSmmHelpers.h
+PchxSmmHelpers.c
+PchSmmUsb.c
+PchSmmGpi.c
+PchSmmPowerButton.c
+PchSmmSw.c
+PchSmmSx.c
+PchSmmPeriodicTimer.c
+IoTrap.c
+PchSmiDispatch.c
+PchSmmEspi.c
+PchSmiHelperClient.c
+
+
+[Protocols]
+gEfiPciRootBridgeIoProtocolGuid ## CONSUMES
+gEfiSmmGpiDispatch2ProtocolGuid ## PRODUCES
+gEfiSmmSxDispatch2ProtocolGuid ## PRODUCES
+gEfiSmmSwDispatch2ProtocolGuid ## PRODUCES
+gEfiSmmUsbDispatch2ProtocolGuid ## PRODUCES
+gEfiSmmPowerButtonDispatch2ProtocolGuid ## PRODUCES
+gEfiSmmPeriodicTimerDispatch2ProtocolGuid ## PRODUCES
+gEfiSmmBase2ProtocolGuid ## CONSUMES
+gEfiSmmCpuProtocolGuid ## CONSUMES
+gEfiSmmReadyToLockProtocolGuid ## CONSUMES
+gEfiSmmIoTrapDispatch2ProtocolGuid ## PRODUCES
+gPchSmmIoTrapControlGuid ## PRODUCES
+gPchTcoSmiDispatchProtocolGuid ## PRODUCES
+gPchPcieSmiDispatchProtocolGuid ## PRODUCES
+gPchAcpiSmiDispatchProtocolGuid ## PRODUCES
+gPchSmiDispatchProtocolGuid ## PRODUCES
+gPchEspiSmiDispatchProtocolGuid ## PRODUCES
+gPchSmmPeriodicTimerControlGuid ## PRODUCES
+gIoTrapExDispatchProtocolGuid ## PRODUCES
+gPchNvsAreaProtocolGuid ## CONSUMES
+
+
+[Guids]
+
+
+[Depex]
+gEfiPciRootBridgeIoProtocolGuid AND
+gEfiPciHostBridgeResourceAllocationProtocolGuid AND ## This is to ensure that PCI MMIO resource has been prepared and available for this driver to allocate.
+gEfiSmmCpuProtocolGuid AND
+gEfiSmmBase2ProtocolGuid AND ## This is for SmmServicesTableLib
+gPchNvsAreaProtocolGuid
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiHelper.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiHelper.h
new file mode 100644
index 0000000000..b224ee650c
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiHelper.h
@@ -0,0 +1,40 @@
+/** @file
+  PCH SMI Helper Header
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_SMI_HELPER_H_
+#define _PCH_SMI_HELPER_H_
+#include <Uefi/UefiBaseType.h>
+
+/**
+  Get Root Port physical Number by CPU or PCH Pcie Root Port Device and Function Number
+
+  @param[in]  RpDev                 Root port device number.
+  @param[in]  RpFun                 Root port function number.
+  @param[out] RpNumber              Return corresponding physical Root Port index (0-based)
+**/
+VOID
+GetPcieRpNumber (
+  IN  UINTN   RpDev,
+  IN  UINTN   RpFun,
+  OUT UINTN   *RpNumber
+  );
+
+/**
+  Get CPU or PCH Pcie Root Port Device and Function Number by Root Port physical Number
+
+  @param[in]  RpNumber              Root port physical number. (0-based)
+  @param[out] RpDev                 Return corresponding root port device number.
+  @param[out] RpFun                 Return corresponding root port function number.
+**/
+VOID
+GetPcieRpDevFun (
+  IN  UINTN   RpIndex,
+  OUT UINTN   *RpDev,
+  OUT UINTN   *RpFun
+  );
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiHelperClient.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiHelperClient.c
new file mode 100644
index 0000000000..7693e76683
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmiHelperClient.c
@@ -0,0 +1,57 @@
+/** @file
+  This file provides function to handle client-server differences.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "PchSmmHelpers.h"
+#include <Register/PmcRegs.h>
+#include <Register/PchPcieRpRegs.h>
+#include <Register/CpuPcieRegs.h>
+#include <Library/CpuPcieInfoFruLib.h>
+#include <Library/CpuPcieRpLib.h>
+#include <CpuPcieInfo.h>
+#include <Library/PchPcieRpLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PchPciBdfLib.h>
+
+/**
+  Get Root Port physical Number by CPU or PCH Pcie Root Port Device and Function Number
+
+  @param[in]  RpDev                 Root port device number.
+  @param[in]  RpFun                 Root port function number.
+  @param[out] RpNumber              Return corresponding physical Root Port index (0-based)
+**/
+VOID
+GetPcieRpNumber (
+  IN  UINTN   RpDev,
+  IN  UINTN   RpFun,
+  OUT UINTN   *RpNumber
+  )
+{
+  UINT64  RpBase;
+  RpBase = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, RpDev, RpFun, 0);
+  GetPchPcieRpNumber (RpDev, RpFun, RpNumber);
+}
+
+/**
+  Get CPU or PCH Pcie Root Port Device and Function Number by Root Port physical Number
+
+  @param[in]  RpNumber              Root port physical number. (0-based)
+  @param[out] RpDev                 Return corresponding root port device number.
+  @param[out] RpFun                 Return corresponding root port function number.
+**/
+VOID
+GetPcieRpDevFun (
+  IN  UINTN   RpIndex,
+  OUT UINTN   *RpDev,
+  OUT UINTN   *RpFun
+  )
+{
+  if (RpIndex >= CpuRpIndex0 && RpIndex <= CpuRpIndex3) {
+    GetCpuPcieRpDevFun ((RpIndex - CpuRpIndex0), RpDev, RpFun);
+  } else {
+    *RpDev = PchPcieRpDevNumber (RpIndex);
+    *RpFun = PchPcieRpFuncNumber (RpIndex);
+  }
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmm.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmm.h
new file mode 100644
index 0000000000..6a23de2bc9
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmm.h
@@ -0,0 +1,1043 @@
+/** @file
+  Prototypes and defines for the PCH SMM Dispatcher.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_SMM_H_
+#define _PCH_SMM_H_
+
+#include <Uefi.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/SmmControl2.h>
+#include <Protocol/SmmUsbDispatch2.h>
+#include <Protocol/SmmSxDispatch2.h>
+#include <Protocol/SmmSwDispatch2.h>
+#include <Protocol/SmmGpiDispatch2.h>
+#include <Protocol/SmmPowerButtonDispatch2.h>
+#include <Protocol/SmmPeriodicTimerDispatch2.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/PerformanceLib.h>
+#include <Protocol/SmmReadyToLock.h>
+#include <IndustryStandard/Pci30.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PchPcieRpLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/GpioLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/EspiLib.h>
+#include <Library/GpioPrivateLib.h>
+#include <Protocol/PchTcoSmiDispatch.h>
+#include <Protocol/PchPcieSmiDispatch.h>
+#include <Protocol/PchAcpiSmiDispatch.h>
+#include <Protocol/PchSmiDispatch.h>
+#include <Protocol/PchEspiSmiDispatch.h>
+#include <Protocol/IoTrapExDispatch.h>
+#include <Library/PmcLib.h>
+#include "IoTrap.h"
+
+#define EFI_BAD_POINTER          0xAFAFAFAFAFAFAFAFULL
+
+extern BOOLEAN                   mReadyToLock;
+
+///
+/// Define an enumeration for all the supported protocols
+///
+#define PCH_SMM_PROTOCOL_TYPE_MAX       6
+
+typedef enum {
+  UsbType,
+  SxType,
+  SwType,
+  GpiType,
+  PowerButtonType,
+  PeriodicTimerType,
+  PchSmiDispatchType,
+  PchSmmProtocolTypeMax
+} PCH_SMM_PROTOCOL_TYPE;
+
+///
+/// Define all the supported types of PCH SMI
+///
+typedef enum {
+  PchTcoSmiMchType,
+  PchTcoSmiTcoTimeoutType,
+  PchTcoSmiOsTcoType,
+  PchTcoSmiNmiType,
+  PchTcoSmiIntruderDetectType,
+  PchTcoSmiSpiBiosWpType,
+  PchTcoSmiLpcBiosWpType,
+  PchTcoSmiNewCenturyType,
+  PchPcieSmiRpHotplugType,
+  PchPcieSmiRpLinkActiveType,
+  PchPcieSmiRpLinkEqType,
+  PchAcpiSmiPmeType,
+  PchAcpiSmiPmeB0Type,
+  PchAcpiSmiRtcAlarmType,
+  PchAcpiSmiTmrOverflowType,
+  PchEspiSmiEspiSlaveType,
+  PchSmiSerialIrqType,
+  PchSmiMcSmiType,
+  PchSmiSmBusType,
+  PchSmiSpiAsyncType,
+  PchIoTrapSmiType                      ///< internal SMI type
+} PCH_SMI_TYPES;
+
+///
+/// Generic funciton pointer to cover all Pch SMI function pointer types
+///
+typedef
+VOID
+(EFIAPI *PCH_SMI_CALLBACK_FUNCTIONS) (
+  IN EFI_HANDLE                         DispatchHandle,
+  ...
+  );
+
+
+///
+/// SPECIFYING A REGISTER
+/// We want a general way of referring to addresses.  For this case, we'll only
+/// need addresses in the ACPI table (and the TCO entries within the ACPI table).
+/// However, it's interesting to consider what it would take to support other types
+/// of addresses.  To address Will's concern, I think it prudent to accommodate it
+/// early on in the design.
+///
+/// Addresses we need to consider:
+///
+///  Type:                           Required:
+///  I/O                             Yes
+///    ACPI (special case of I/O)    Only if we want to
+///    TCO  (special case of I/O)    Only if we want to
+///  GPIO  (special case of MMIO)    Only if we want to
+///  Memory (or Memory Mapped I/O)   Only if we want to
+///  PCIE                            Yes, for BiosWp
+///
+typedef enum {
+  ///
+  ///  IO_ADDR_TYPE, /// unimplemented
+  ///
+  ACPI_ADDR_TYPE,
+  TCO_ADDR_TYPE,
+  ///
+  ///  MEMORY_ADDR_TYPE, /// unimplemented
+  ///
+  GPIO_ADDR_TYPE,
+  MEMORY_MAPPED_IO_ADDRESS_TYPE,
+  PCIE_ADDR_TYPE,
+  PCR_ADDR_TYPE,
+  NUM_ADDR_TYPES,                     ///< count of items in this enum
+  PCH_SMM_ADDR_TYPE_NULL        = -1  ///< sentinel to indicate NULL or to signal end of arrays
+} ADDR_TYPE;
+
+//
+// Assumption: 32-bits -- enum's evaluate to integer
+// Assumption: This code will only run on IA-32.  Justification: IA-64 doesn't have SMIs.
+// We don't have to worry about 64-bit addresses.
+// Typedef the size of addresses in case the numbers I'm using are wrong or in case
+// this changes.  This is a good idea because PCI_ADDR will change, for example, when
+// we add support for PciExpress.
+//
+typedef UINT16 IO_ADDR;
+typedef IO_ADDR ACPI_ADDR;  ///< can omit
+typedef IO_ADDR TCO_ADDR;   ///< can omit
+typedef UINTN MEM_ADDR;
+typedef MEM_ADDR *MEMORY_MAPPED_IO_ADDRESS;
+typedef MEM_ADDR *GPIO_ADDR;
+typedef union {
+  UINT32  Raw;
+  struct {
+    UINT32 Reg: 16;
+    UINT32 Fnc: 3;
+    UINT32 Dev: 5;
+    UINT32 Bus: 8;
+  } Fields;
+} PCIE_ADDR;
+
+typedef union {
+  UINT32  Raw;
+  struct {
+    UINT16 Offset;
+    UINT8  Pid;
+    UINT8  Base;
+  } Fields;
+} PCR_ADDR;
+
+typedef struct {
+  ADDR_TYPE Type;
+  union {
+    ///
+    /// used to initialize during declaration/definition
+    ///
+    UINT32                    raw;
+
+    ///
+    /// used to access useful data
+    ///
+    IO_ADDR                   io;
+    ACPI_ADDR                 acpi;
+    TCO_ADDR                  tco;
+    GPIO_ADDR                 gpio;
+    MEM_ADDR                  mem;
+    MEMORY_MAPPED_IO_ADDRESS  Mmio;
+    PCIE_ADDR                 pcie;
+    PCR_ADDR                  Pcr;
+
+  } Data;
+
+} PCH_SMM_ADDRESS;
+
+///
+/// SPECIFYING BITS WITHIN A REGISTER
+/// Here's a struct that helps us specify a source or enable bit.
+///
+typedef struct {
+  PCH_SMM_ADDRESS Reg;
+  UINT8           SizeInBytes;  ///< of the register
+  UINT8           Bit;
+} PCH_SMM_BIT_DESC;
+
+//
+// Sometimes, we'll have bit descriptions that are unused.  It'd be great to have a
+// way to easily identify them:
+//
+#define IS_BIT_DESC_NULL(BitDesc)   ((BitDesc).Reg.Type == PCH_SMM_ADDR_TYPE_NULL)  ///< "returns" true when BitDesc is NULL
+#define NULL_THIS_BIT_DESC(BitDesc) ((BitDesc).Reg.Type = PCH_SMM_ADDR_TYPE_NULL)   ///< will "return" an integer w/ value of 0
+#define NULL_BIT_DESC_INITIALIZER \
+  { \
+    { \
+      PCH_SMM_ADDR_TYPE_NULL, \
+      { \
+        0 \
+      } \
+    }, \
+    0, 0 \
+  }
+//
+// I'd like a type to specify the callback's Sts & En bits because they'll
+// be commonly used together:
+//
+#define NUM_EN_BITS   2
+#define NUM_STS_BITS  1
+
+//
+// Flags
+//
+typedef UINT8 PCH_SMM_SOURCE_FLAGS;
+
+//
+// Flags required to describe the event source
+//
+#define PCH_SMM_NO_FLAGS          0
+#define PCH_SMM_SCI_EN_DEPENDENT  1
+
+typedef struct {
+  PCH_SMM_SOURCE_FLAGS  Flags;
+  PCH_SMM_BIT_DESC      En[NUM_EN_BITS];    ///< Describes the enable bit(s) for the SMI event
+  PCH_SMM_BIT_DESC      Sts[NUM_STS_BITS];  ///< Describes the secondary status bit for the SMI event. Might be the same as TopLevelSmi
+  PCH_SMM_BIT_DESC      PmcSmiSts;          ///< Refereing to the top level status bit in PMC SMI_STS, i.e. R_PCH_SMI_STS
+} PCH_SMM_SOURCE_DESC;
+
+///
+/// Used to initialize null source descriptor
+///
+#define NULL_SOURCE_DESC_INITIALIZER \
+  { \
+    PCH_SMM_NO_FLAGS, \
+    { \
+      NULL_BIT_DESC_INITIALIZER, NULL_BIT_DESC_INITIALIZER \
+    }, \
+    { \
+      NULL_BIT_DESC_INITIALIZER \
+    }, \
+    NULL_BIT_DESC_INITIALIZER \
+  }
+
+///
+/// Define a PCIE RP event context for SmiProfileHandlerInfo tool
+///
+typedef struct {
+  PCH_SMI_TYPES               PchSmiType;
+  UINTN                       RpIndex;
+} PCH_SMM_PCIE_REGISTER_CONTEXT;
+
+///
+/// CHILD CONTEXTS
+/// To keep consistent w/ the architecture, we'll need to provide the context
+/// to the child when we call its callback function.  After talking with Will,
+/// we agreed that we'll need functions to "dig" the context out of the hardware
+/// in many cases (Sx, Trap, Gpi, etc), and we'll need a function to compare those
+/// contexts to prevent unnecessary dispatches.  I'd like a general type for these
+/// "GetContext" functions, so I'll need a union of all the protocol contexts for
+/// our internal use:
+///
+typedef union {
+  //
+  // (in no particular order)
+  //
+  EFI_SMM_SX_REGISTER_CONTEXT             Sx;
+  EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT PeriodicTimer;
+  EFI_SMM_SW_REGISTER_CONTEXT             Sw;
+  EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT   PowerButton;
+  EFI_SMM_USB_REGISTER_CONTEXT            Usb;
+  EFI_SMM_GPI_REGISTER_CONTEXT            Gpi;
+  PCH_SMM_PCIE_REGISTER_CONTEXT           Pcie;
+} PCH_SMM_CONTEXT;
+
+///
+/// Misc data for PchDispatcher usage.
+/// For PeriodicTimer, since the ElapsedTime is removed from EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT of EDKII,
+/// and PchDispatcher needs it for every record. Thus move it here to support ElapsedTime.
+///
+typedef struct {
+  UINTN    ElapsedTime;
+  ///
+  /// A switch to control periodic timer SMI enabling
+  ///
+  BOOLEAN  TimerSmiEnabled;
+} PCH_SMM_MISC_DATA;
+
+//
+// Assumption: PeriodicTimer largest at 3x64-bits or 24 bytes
+//
+typedef struct _DATABASE_RECORD DATABASE_RECORD;
+
+///
+/// Assumption: the GET_CONTEXT function will be as small and simple as possible.
+/// Assumption: We don't need to pass in an enumeration for the protocol because each
+///    GET_CONTEXT function is written for only one protocol.
+/// We also need a function to compare contexts to see if the child should be dispatched
+/// In addition, we need a function to acquire CommBuffer and CommBufferSize for
+///    dispatch callback function of EDKII native support.
+///
+typedef
+VOID
+(EFIAPI *GET_CONTEXT) (
+  IN  DATABASE_RECORD    * Record,
+  OUT PCH_SMM_CONTEXT    * Context
+  );
+
+typedef
+BOOLEAN
+(EFIAPI *CMP_CONTEXT) (
+  IN PCH_SMM_CONTEXT     * Context1,
+  IN PCH_SMM_CONTEXT     * Context2
+  );
+
+typedef
+VOID
+(EFIAPI *GET_COMMBUFFER) (
+  IN  DATABASE_RECORD    * Record,
+  OUT VOID               **CommBuffer,
+  OUT UINTN              * CommBufferSize
+  );
+
+///
+/// Finally, every protocol will require a "Get Context" and "Compare Context" call, so
+/// we may as well wrap that up in a table, too.
+///
+typedef struct {
+  GET_CONTEXT     GetContext;
+  CMP_CONTEXT     CmpContext;
+  GET_COMMBUFFER  GetCommBuffer;
+} CONTEXT_FUNCTIONS;
+
+extern CONTEXT_FUNCTIONS          ContextFunctions[PCH_SMM_PROTOCOL_TYPE_MAX];
+
+///
+/// MAPPING CONTEXT TO BIT DESCRIPTIONS
+/// I'd like to have a general approach to mapping contexts to bit descriptions.
+/// Sometimes, we'll find that we can use table lookups or constant assignments;
+/// other times, we'll find that we'll need to use a function to perform the mapping.
+/// If we define a macro to mask that process, we'll never have to change the code.
+/// I don't know if this is desirable or not -- if it isn't, then we can get rid
+/// of the macros and just use function calls or variable assignments.  Doesn't matter
+/// to me.
+/// Mapping complex contexts requires a function
+///
+
+/**
+  Maps a USB context to a source description.
+
+  @param[in] Context              The context we need to map.  Type must be USB.
+  @param[out] SrcDesc             The source description that corresponds to the given context.
+
+**/
+VOID
+MapUsbToSrcDesc (
+  IN  PCH_SMM_CONTEXT         *Context,
+  OUT PCH_SMM_SOURCE_DESC     *SrcDesc
+  );
+
+/**
+  Figure out which timer the child is requesting and
+  send back the source description
+
+  @param[in] DispatchContext      The pointer to the Dispatch Context instances
+  @param[out] SrcDesc             The pointer to the source description
+
+**/
+VOID
+MapPeriodicTimerToSrcDesc (
+  IN  PCH_SMM_CONTEXT                                         *DispatchContext,
+  OUT PCH_SMM_SOURCE_DESC                                     *SrcDesc
+  );
+
+//
+// Mapping simple contexts can be done by assignment or lookup table
+//
+extern CONST PCH_SMM_SOURCE_DESC  mSxSourceDesc;
+extern CONST PCH_SMM_SOURCE_DESC  mPowerButtonSourceDesc;
+extern CONST PCH_SMM_SOURCE_DESC  mSrcDescNewCentury;
+extern CONST PCH_SMM_SOURCE_DESC  mGpiSourceDescTemplate;
+
+///
+/// For PCHx, APMC is UINT8 port, so the MAX SWI Value is 0xFF.
+///
+#define MAXIMUM_SWI_VALUE 0xFF
+///
+/// Open: Need to make sure this kind of type cast will actually work.
+///   May need an intermediate form w/ two VOID* arguments.  I'll figure
+///   that out when I start compiling.
+///
+typedef
+VOID
+(EFIAPI *PCH_SMM_CLEAR_SOURCE) (
+  CONST PCH_SMM_SOURCE_DESC * SrcDesc
+  );
+
+///
+/// "DATABASE" RECORD
+/// Linked list data structures
+///
+#define DATABASE_RECORD_SIGNATURE SIGNATURE_32 ('D', 'B', 'R', 'C')
+
+struct _DATABASE_RECORD {
+  UINT32                        Signature;
+  LIST_ENTRY                    Link;
+  BOOLEAN                       Processed;
+  ///
+  /// Status and Enable bit description
+  ///
+  PCH_SMM_SOURCE_DESC           SrcDesc;
+
+  ///
+  /// Callback function
+  ///
+  EFI_SMM_HANDLER_ENTRY_POINT2  Callback;
+  PCH_SMM_CONTEXT               ChildContext;
+  UINTN                         ContextSize;
+
+  ///
+  /// Special handling hooks -- init them to NULL if unused/unneeded
+  ///
+  PCH_SMM_CLEAR_SOURCE          ClearSource;
+
+  ///
+  /// Functions required to make callback code general
+  ///
+  CONTEXT_FUNCTIONS             ContextFunctions;
+
+  ///
+  /// The protocol that this record dispatches
+  ///
+  PCH_SMM_PROTOCOL_TYPE         ProtocolType;
+
+  ///
+  /// Misc data for private usage
+  ///
+  PCH_SMM_MISC_DATA             MiscData;
+
+  ///
+  /// PCH SMI callback function
+  ///
+  PCH_SMI_CALLBACK_FUNCTIONS    PchSmiCallback;
+  ///
+  /// Indicate the PCH SMI types.
+  ///
+  PCH_SMI_TYPES                 PchSmiType;
+};
+
+#define DATABASE_RECORD_FROM_LINK(_record)  CR (_record, DATABASE_RECORD, Link, DATABASE_RECORD_SIGNATURE)
+#define DATABASE_RECORD_FROM_CHILDCONTEXT(_record)  CR (_record, DATABASE_RECORD, ChildContext, DATABASE_RECORD_SIGNATURE)
+
+///
+/// HOOKING INTO THE ARCHITECTURE
+///
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SMM_GENERIC_REGISTER) (
+  IN  VOID                                    **This,
+  IN  VOID                                    *DispatchFunction,
+  IN  VOID                                    *DispatchContext,
+  OUT EFI_HANDLE                              *DispatchHandle
+  );
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SMM_GENERIC_UNREGISTER) (
+  IN  VOID                                    **This,
+  IN  EFI_HANDLE                              DispatchHandle
+  );
+
+///
+/// Define a memory "stamp" equivalent in size and function to most of the protocols
+///
+typedef struct {
+  PCH_SMM_GENERIC_REGISTER    Register;
+  PCH_SMM_GENERIC_UNREGISTER  Unregister;
+  UINTN                       Extra1;
+  UINTN                       Extra2; ///< may not need this one
+} PCH_SMM_GENERIC_PROTOCOL;
+
+/**
+  Register a child SMI dispatch function with a parent SMM driver.
+
+  @param[in] This                 Pointer to the PCH_SMM_GENERIC_PROTOCOL instance.
+  @param[in] DispatchFunction     Pointer to dispatch function to be invoked for this SMI source.
+  @param[in] DispatchContext      Pointer to the dispatch function's context.
+  @param[out] DispatchHandle      Handle of dispatch function, for when interfacing
+                                  with the parent SMM driver, will be the address of linked
+                                  list link in the call back record.
+
+  @retval EFI_OUT_OF_RESOURCES    Insufficient resources to create database record
+  @retval EFI_INVALID_PARAMETER   The input parameter is invalid
+  @retval EFI_SUCCESS             The dispatch function has been successfully
+                                  registered and the SMI source has been enabled.
+**/
+EFI_STATUS
+EFIAPI
+PchPiSmmCoreRegister (
+  IN  PCH_SMM_GENERIC_PROTOCOL                          *This,
+  IN  EFI_SMM_HANDLER_ENTRY_POINT2                      DispatchFunction,
+  IN  PCH_SMM_CONTEXT                                   *DispatchContext,
+  OUT EFI_HANDLE                                        *DispatchHandle
+  );
+
+/**
+  Unregister a child SMI source dispatch function with a parent SMM driver
+
+  @param[in] This                       Protocol instance pointer.
+  @param[in] DispatchHandle             Handle of dispatch function to deregister.
+
+  @retval EFI_SUCCESS                   The dispatch function has been successfully
+                                        unregistered and the SMI source has been disabled
+                                        if there are no other registered child dispatch
+                                        functions for this SMI source.
+  @retval EFI_INVALID_PARAMETER         Handle is invalid.
+  @retval EFI_ACCESS_DENIED             Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+PchPiSmmCoreUnRegister (
+  IN PCH_SMM_GENERIC_PROTOCOL                           *This,
+  IN EFI_HANDLE                                         *DispatchHandle
+  );
+
+
+/**
+  Unregister a child SMI source dispatch function with a parent SMM driver.
+
+  @param[in] This                 Pointer to the PCH_SMM_GENERIC_PROTOCOL instance.
+  @param[in] DispatchHandle       Handle of dispatch function to deregister.
+
+  @retval EFI_SUCCESS             The dispatch function has been successfully
+                                  unregistered and the SMI source has been disabled
+                                  if there are no other registered child dispatch
+                                  functions for this SMI source.
+  @retval EFI_INVALID_PARAMETER   Handle is invalid.
+**/
+EFI_STATUS
+EFIAPI
+PchSmmCoreUnRegister (
+  IN  PCH_SMM_GENERIC_PROTOCOL                         *This,
+  IN  EFI_HANDLE                                       *DispatchHandle
+  );
+
+typedef union {
+  PCH_SMM_GENERIC_PROTOCOL                    Generic;
+  EFI_SMM_USB_DISPATCH2_PROTOCOL              Usb;
+  EFI_SMM_SX_DISPATCH2_PROTOCOL               Sx;
+  EFI_SMM_SW_DISPATCH2_PROTOCOL               Sw;
+  EFI_SMM_GPI_DISPATCH2_PROTOCOL              Gpi;
+  EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL     PowerButton;
+  EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL   PeriodicTimer;
+} PCH_SMM_PROTOCOL;
+
+///
+/// Define a structure to help us identify the generic protocol
+///
+#define PROTOCOL_SIGNATURE  SIGNATURE_32 ('P', 'R', 'O', 'T')
+
+typedef struct {
+  UINTN                 Signature;
+
+  PCH_SMM_PROTOCOL_TYPE Type;
+  EFI_GUID              *Guid;
+  PCH_SMM_PROTOCOL      Protocols;
+} PCH_SMM_QUALIFIED_PROTOCOL;
+
+#define QUALIFIED_PROTOCOL_FROM_GENERIC(_generic) \
+  CR ( \
+  _generic, \
+  PCH_SMM_QUALIFIED_PROTOCOL, \
+  Protocols, \
+  PROTOCOL_SIGNATURE \
+  )
+
+///
+/// Create private data for the protocols that we'll publish
+///
+typedef struct {
+  LIST_ENTRY                  CallbackDataBase;
+  EFI_HANDLE                  SmiHandle;
+  EFI_HANDLE                  InstallMultProtHandle;
+  PCH_SMM_QUALIFIED_PROTOCOL  Protocols[PCH_SMM_PROTOCOL_TYPE_MAX];
+} PRIVATE_DATA;
+
+extern PRIVATE_DATA           mPrivateData;
+extern UINT16                 mAcpiBaseAddr;
+extern UINT16                 mTcoBaseAddr;
+
+/**
+  The internal function used to create and insert a database record
+
+  @param[in]  InsertRecord              Record to insert to database.
+  @param[out] DispatchHandle            Handle of dispatch function to register.
+
+  @retval EFI_INVALID_PARAMETER         Error with NULL SMI source description
+  @retval EFI_OUT_OF_RESOURCES          Fail to allocate pool for database record
+  @retval EFI_SUCCESS                   The database record is created successfully.
+**/
+EFI_STATUS
+SmmCoreInsertRecord (
+  IN  DATABASE_RECORD                   *NewRecord,
+  OUT EFI_HANDLE                        *DispatchHandle
+  );
+
+/**
+  Get the Sleep type
+
+  @param[in] Record               No use
+  @param[out] Context             The context that includes SLP_TYP bits to be filled
+**/
+VOID
+EFIAPI
+SxGetContext (
+  IN  DATABASE_RECORD    *Record,
+  OUT PCH_SMM_CONTEXT    *Context
+  );
+
+/**
+  Register a child SMI source dispatch function for the specified software SMI.
+
+  This service registers a function (DispatchFunction) which will be called when the software
+  SMI source specified by RegisterContext->SwSmiCpuIndex is detected. On return,
+  DispatchHandle contains a unique handle which may be used later to unregister the function
+  using UnRegister().
+
+  @param[in]  This                 Pointer to the EFI_SMM_SW_DISPATCH2_PROTOCOL instance.
+  @param[in]  DispatchFunction     Function to register for handler when the specified software
+                                   SMI is generated.
+  @param[in, out] RegisterContext  Pointer to the dispatch function's context.
+                                   The caller fills this context in before calling
+                                   the register function to indicate to the register
+                                   function which Software SMI input value the
+                                   dispatch function should be invoked for.
+  @param[out] DispatchHandle       Handle generated by the dispatcher to track the
+                                   function instance.
+
+  @retval EFI_SUCCESS            The dispatch function has been successfully
+                                 registered and the SMI source has been enabled.
+  @retval EFI_DEVICE_ERROR       The SW driver was unable to enable the SMI source.
+  @retval EFI_INVALID_PARAMETER  RegisterContext is invalid. The SW SMI input value
+                                 is not within a valid range or is already in use.
+  @retval EFI_OUT_OF_RESOURCES   There is not enough memory (system or SMM) to manage this
+                                 child.
+  @retval EFI_OUT_OF_RESOURCES   A unique software SMI value could not be assigned
+                                 for this dispatch.
+**/
+EFI_STATUS
+EFIAPI
+PchSwSmiRegister (
+  IN  EFI_SMM_SW_DISPATCH2_PROTOCOL       *This,
+  IN  EFI_SMM_HANDLER_ENTRY_POINT2        DispatchFunction,
+  IN  EFI_SMM_SW_REGISTER_CONTEXT         *DispatchContext,
+  OUT EFI_HANDLE                          *DispatchHandle
+  );
+
+/**
+  Unregister a child SMI source dispatch function for the specified software SMI.
+
+  This service removes the handler associated with DispatchHandle so that it will no longer be
+  called in response to a software SMI.
+
+  @param[in] This                Pointer to the EFI_SMM_SW_DISPATCH2_PROTOCOL instance.
+  @param[in] DispatchHandle      Handle of dispatch function to deregister.
+
+  @retval EFI_SUCCESS            The dispatch function has been successfully unregistered.
+  @retval EFI_INVALID_PARAMETER  The DispatchHandle was not valid.
+**/
+EFI_STATUS
+EFIAPI
+PchSwSmiUnRegister (
+  IN CONST EFI_SMM_SW_DISPATCH2_PROTOCOL  *This,
+  IN       EFI_HANDLE                     DispatchHandle
+  );
+
+/**
+  Init required protocol for Pch Sw Dispatch protocol.
+**/
+VOID
+PchSwDispatchInit (
+  VOID
+  );
+
+/**
+  Check whether sleep type of two contexts match
+
+  @param[in] Context1             Context 1 that includes sleep type 1
+  @param[in] Context2             Context 2 that includes sleep type 2
+
+  @retval FALSE                   Sleep types match
+  @retval TRUE                    Sleep types don't match
+**/
+BOOLEAN
+EFIAPI
+SxCmpContext (
+  IN PCH_SMM_CONTEXT     *Context1,
+  IN PCH_SMM_CONTEXT     *Context2
+  );
+
+/**
+  Update the elapsed time from the Interval data of DATABASE_RECORD
+
+  @param[in] Record               The pointer to the DATABASE_RECORD.
+  @param[out] HwContext           The Context to be updated.
+**/
+VOID
+EFIAPI
+PeriodicTimerGetContext (
+  IN  DATABASE_RECORD    *Record,
+  OUT PCH_SMM_CONTEXT    *Context
+  );
+
+/**
+  Check whether Periodic Timer of two contexts match
+
+  @param[in] Context1             Context 1 that includes Periodic Timer  1
+  @param[in] Context2             Context 2 that includes Periodic Timer  2
+
+  @retval FALSE                   Periodic Timer match
+  @retval TRUE                    Periodic Timer don't match
+**/
+BOOLEAN
+EFIAPI
+PeriodicTimerCmpContext (
+  IN PCH_SMM_CONTEXT     *Context1,
+  IN PCH_SMM_CONTEXT     *Context2
+  );
+
+/**
+  Gather the CommBuffer information of SmmPeriodicTimerDispatch2.
+
+  @param[in]  Record              No use
+  @param[out] CommBuffer          Point to the CommBuffer structure
+  @param[out] CommBufferSize      Point to the Size of CommBuffer structure
+**/
+VOID
+EFIAPI
+PeriodicTimerGetCommBuffer (
+  IN  DATABASE_RECORD    *Record,
+  OUT VOID               **CommBuffer,
+  OUT UINTN              *CommBufferSize
+  );
+
+/**
+  Get the power button status.
+
+  @param[in] Record               The pointer to the DATABASE_RECORD.
+  @param[out] Context             Calling context from the hardware, will be updated with the current power button status.
+**/
+VOID
+EFIAPI
+PowerButtonGetContext (
+  IN  DATABASE_RECORD    *Record,
+  OUT PCH_SMM_CONTEXT    *Context
+  );
+
+/**
+  Check whether Power Button status of two contexts match
+
+  @param[in] Context1             Context 1 that includes Power Button status 1
+  @param[in] Context2             Context 2 that includes Power Button status 2
+
+  @retval FALSE                   Power Button status match
+  @retval TRUE                    Power Button status don't match
+**/
+BOOLEAN
+EFIAPI
+PowerButtonCmpContext (
+  IN PCH_SMM_CONTEXT     *Context1,
+  IN PCH_SMM_CONTEXT     *Context2
+  );
+
+/**
+  This function is responsible for calculating and enabling any timers that are required
+  to dispatch messages to children. The SrcDesc argument isn't acutally used.
+
+  @param[in] SrcDesc              Pointer to the PCH_SMM_SOURCE_DESC instance.
+**/
+VOID
+EFIAPI
+PchSmmPeriodicTimerClearSource (
+  IN CONST PCH_SMM_SOURCE_DESC    *SrcDesc
+  );
+
+/**
+  This services returns the next SMI tick period that is supported by the chipset.
+  The order returned is from longest to shortest interval period.
+
+  @param[in] This                 Pointer to the EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL instance.
+  @param[in, out] SmiTickInterval Pointer to pointer of the next shorter SMI interval period that is supported by the child.
+
+  @retval EFI_SUCCESS             The service returned successfully.
+  @retval EFI_INVALID_PARAMETER   The parameter SmiTickInterval is invalid.
+**/
+EFI_STATUS
+PchSmmPeriodicTimerDispatchGetNextShorterInterval (
+  IN CONST EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL    *This,
+  IN OUT UINT64                                         **SmiTickInterval
+  );
+
+/**
+  Install PCH SMM periodic timer control protocol
+
+  @param[in] Handle                     handle for this driver
+
+  @retval EFI_SUCCESS                   Driver initialization completed successfully
+**/
+EFI_STATUS
+EFIAPI
+InstallPchSmmPeriodicTimerControlProtocol (
+  IN EFI_HANDLE                         Handle
+  );
+
+/**
+  When we get an SMI that indicates that we are transitioning to a sleep state,
+  we need to actually transition to that state.  We do this by disabling the
+  "SMI on sleep enable" feature, which generates an SMI when the operating system
+  tries to put the system to sleep, and then physically putting the system to sleep.
+**/
+VOID
+PchSmmSxGoToSleep (
+  VOID
+  );
+
+/**
+  Install protocols of PCH specifics SMI types, including
+  PCH TCO SMI types, PCH PCIE SMI types, PCH ACPI SMI types, PCH MISC SMI types.
+
+  @retval                               the result of protocol installation
+**/
+EFI_STATUS
+InstallPchSmiDispatchProtocols (
+  VOID
+  );
+
+/**
+  The function to dispatch all callback function of PCH SMI types.
+
+  @retval EFI_SUCCESS                   Function successfully completed
+  @retval EFI_UNSUPPORTED               no
+**/
+EFI_STATUS
+PchSmiTypeCallbackDispatcher (
+  IN  DATABASE_RECORD                   *Record
+  );
+
+/**
+  The register function used to register SMI handler of IoTrap event.
+  This is internal function and only used by Iotrap module.
+
+  @param[in]  DispatchFunction          Pointer to dispatch function to be invoked for this SMI source
+  @param[in]  IoTrapIndex               Index number of IOTRAP register
+  @param[out] DispatchHandle            Handle of dispatch function to register.
+
+  @retval EFI_INVALID_PARAMETER         Error with NULL SMI source description
+  @retval EFI_OUT_OF_RESOURCES          Fail to allocate pool for database record
+  @retval EFI_SUCCESS                   The database record is created successfully.
+**/
+EFI_STATUS
+PchInternalIoTrapSmiRegister (
+  IN  PCH_SMI_DISPATCH_CALLBACK         DispatchFunction,
+  IN  UINTN                             IoTrapIndex,
+  OUT EFI_HANDLE                        *DispatchHandle
+  );
+
+/**
+  Unregister a child SMI source dispatch function with a parent SMM driver
+
+  @param[in] DispatchHandle             Handle of dispatch function to deregister.
+
+  @retval EFI_SUCCESS                   The dispatch function has been successfully
+                                        unregistered and the SMI source has been disabled
+                                        if there are no other registered child dispatch
+                                        functions for this SMI source.
+  @retval EFI_INVALID_PARAMETER         Handle is invalid.
+**/
+EFI_STATUS
+PchInternalIoTrapSmiUnRegister (
+  IN  EFI_HANDLE                        DispatchHandle
+  );
+
+/**
+  Register an eSPI SMI handler based on the type
+
+  @param[in]  DispatchFunction        Callback in an event of eSPI SMI
+  @param[in]  PchSmiTypes             The eSPI type published by PchSmiDispatch
+  @param[out] DispatchHandle          The callback handle
+
+  @retval     EFI_INVALID_PARAMETER   Error with NULL SMI source description
+  @retval     EFI_OUT_OF_RESOURCES    Fail to allocate pool for database record
+  @retval     EFI_SUCCESS             Registration is successful.
+**/
+EFI_STATUS
+PchInternalEspiSmiRegister (
+  IN  PCH_SMI_DISPATCH_CALLBACK         DispatchFunction,
+  IN  PCH_SMI_TYPES                     PchSmiTypes,
+  OUT EFI_HANDLE                        *DispatchHandle
+  );
+
+/**
+  Unregister an eSPI SMI handler
+
+  @param[in] DispatchHandle             Handle of dispatch function to deregister.
+
+  @retval EFI_SUCCESS                   The dispatch function has been successfully
+                                        unregistered and the SMI source has been disabled
+                                        if there are no other registered child dispatch
+                                        functions for this SMI source.
+  @retval EFI_INVALID_PARAMETER         Handle is invalid.
+**/
+EFI_STATUS
+PchInternalEspiSmiUnRegister (
+  IN  EFI_HANDLE                        DispatchHandle
+  );
+
+/**
+  The internal function used to create and insert a database record
+  for SMI record of Pch Smi types.
+
+  @param[in]  SrcDesc                   The pointer to the SMI source description
+  @param[in]  DispatchFunction          Pointer to dispatch function to be invoked for this SMI source
+  @param[in]  PchSmiType                Specific SMI type of PCH SMI
+  @param[out] DispatchHandle            Handle of dispatch function to register.
+
+  @retval EFI_INVALID_PARAMETER         Error with NULL SMI source description
+  @retval EFI_OUT_OF_RESOURCES          Fail to allocate pool for database record
+  @retval EFI_SUCCESS                   The database record is created successfully.
+**/
+EFI_STATUS
+PchSmiRecordInsert (
+  IN  CONST PCH_SMM_SOURCE_DESC         *SrcDesc,
+  IN  PCH_SMI_CALLBACK_FUNCTIONS        DispatchFunction,
+  IN  PCH_SMI_TYPES                     PchSmiType,
+  OUT EFI_HANDLE                        *DispatchHandle
+  );
+
+extern CONST PCH_SMM_SOURCE_DESC mSrcDescSerialIrq;
+extern CONST PCH_SMM_SOURCE_DESC mSrcDescLpcBiosWp;
+
+/**
+  Clear the TCO SMI status bit and block after the SMI handling is done
+
+  @param[in] SrcDesc                    Pointer to the PCH SMI source description table
+
+**/
+VOID
+EFIAPI
+PchTcoSmiClearSourceAndBlock (
+  CONST PCH_SMM_SOURCE_DESC             *SrcDesc
+  );
+
+/**
+  Clear the TCO SMI status bit after the SMI handling is done
+
+  @param[in] SrcDesc                    Pointer to the PCH SMI source description table
+
+**/
+VOID
+EFIAPI
+PchTcoSmiClearSource (
+  CONST PCH_SMM_SOURCE_DESC             *SrcDesc
+  );
+
+/**
+  Initialize Source descriptor structure
+
+  @param[in] SrcDesc                    Pointer to the PCH SMI source description table
+**/
+VOID
+EFIAPI
+NullInitSourceDesc (
+  PCH_SMM_SOURCE_DESC                   *SrcDesc
+  );
+
+/**
+  The register function used to register SMI handler of GPI SMI event.
+
+  @param[in]  This               Pointer to the EFI_SMM_GPI_DISPATCH2_PROTOCOL instance.
+  @param[in]  DispatchFunction   Function to register for handler when the specified GPI causes an SMI.
+  @param[in]  RegisterContext    Pointer to the dispatch function's context.
+                                 The caller fills this context in before calling
+                                 the register function to indicate to the register
+                                 function the GPI(s) for which the dispatch function
+                                 should be invoked.
+  @param[out] DispatchHandle     Handle generated by the dispatcher to track the
+                                 function instance.
+
+  @retval EFI_SUCCESS            The dispatch function has been successfully
+                                 registered and the SMI source has been enabled.
+  @retval EFI_ACCESS_DENIED      Register is not allowed
+  @retval EFI_INVALID_PARAMETER  RegisterContext is invalid. The GPI input value
+                                 is not within valid range.
+  @retval EFI_OUT_OF_RESOURCES   There is not enough memory (system or SMM) to manage this child.
+**/
+EFI_STATUS
+EFIAPI
+PchGpiSmiRegister (
+  IN CONST EFI_SMM_GPI_DISPATCH2_PROTOCOL  *This,
+  IN       EFI_SMM_HANDLER_ENTRY_POINT2    DispatchFunction,
+  IN       EFI_SMM_GPI_REGISTER_CONTEXT    *RegisterContext,
+  OUT      EFI_HANDLE                      *DispatchHandle
+  );
+
+/**
+  Unregister a GPI SMI source dispatch function with a parent SMM driver
+
+  @param[in] This                 Pointer to the EFI_SMM_GPI_DISPATCH2_PROTOCOL instance.
+  @param[in] DispatchHandle       Handle of dispatch function to deregister.
+
+  @retval EFI_SUCCESS             The dispatch function has been successfully
+                                  unregistered and the SMI source has been disabled
+                                  if there are no other registered child dispatch
+                                  functions for this SMI source.
+  @retval EFI_INVALID_PARAMETER   Handle is invalid.
+**/
+EFI_STATUS
+EFIAPI
+PchGpiSmiUnRegister (
+  IN CONST EFI_SMM_GPI_DISPATCH2_PROTOCOL  *This,
+  IN       EFI_HANDLE                      DispatchHandle
+  );
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmCore.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmCore.c
new file mode 100644
index 0000000000..b2e76a8b72
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmCore.c
@@ -0,0 +1,926 @@
+/** @file
+  This driver is responsible for the registration of child drivers
+  and the abstraction of the PCH SMI sources.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "PchSmm.h"
+#include "PchSmmHelpers.h"
+#include "PchSmmEspi.h"
+#include <Library/SmiHandlerProfileLib.h>
+#include <Register/GpioRegs.h>
+#include <Register/PmcRegs.h>
+#include <Register/RtcRegs.h>
+
+#define PROGRESS_CODE_S3_SUSPEND_START  PcdGet32 (PcdProgressCodeS3SuspendStart)
+//
+// MODULE / GLOBAL DATA
+//
+// Module variables used by the both the main dispatcher and the source dispatchers
+// Declared in PchSmm.h
+//
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16                mAcpiBaseAddr;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16                mTcoBaseAddr;
+GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN               mReadyToLock;
+GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN               mS3SusStart;
+
+GLOBAL_REMOVE_IF_UNREFERENCED PRIVATE_DATA          mPrivateData = {
+  {
+    NULL,
+    NULL
+  },                                    // CallbackDataBase linked list head
+  NULL,                                 // EFI handle returned when calling InstallMultipleProtocolInterfaces
+  NULL,                                 //
+  {                                     // protocol arrays
+    //
+    // elements within the array
+    //
+    {
+      PROTOCOL_SIGNATURE,
+      UsbType,
+      &gEfiSmmUsbDispatch2ProtocolGuid,
+      {{
+        (PCH_SMM_GENERIC_REGISTER) PchPiSmmCoreRegister,
+        (PCH_SMM_GENERIC_UNREGISTER) PchPiSmmCoreUnRegister
+      }}
+    },
+    {
+      PROTOCOL_SIGNATURE,
+      SxType,
+      &gEfiSmmSxDispatch2ProtocolGuid,
+      {{
+        (PCH_SMM_GENERIC_REGISTER) PchPiSmmCoreRegister,
+        (PCH_SMM_GENERIC_UNREGISTER) PchPiSmmCoreUnRegister
+      }}
+    },
+    {
+      PROTOCOL_SIGNATURE,
+      SwType,
+      &gEfiSmmSwDispatch2ProtocolGuid,
+      {{
+        (PCH_SMM_GENERIC_REGISTER) PchSwSmiRegister,
+        (PCH_SMM_GENERIC_UNREGISTER) PchSwSmiUnRegister,
+        (UINTN) MAXIMUM_SWI_VALUE
+      }}
+    },
+    {
+      PROTOCOL_SIGNATURE,
+      GpiType,
+      &gEfiSmmGpiDispatch2ProtocolGuid,
+      {{
+        (PCH_SMM_GENERIC_REGISTER) PchGpiSmiRegister,
+        (PCH_SMM_GENERIC_UNREGISTER) PchGpiSmiUnRegister,
+        (UINTN) PCH_GPIO_NUM_SUPPORTED_GPIS
+      }}
+    },
+    {
+      PROTOCOL_SIGNATURE,
+      PowerButtonType,
+      &gEfiSmmPowerButtonDispatch2ProtocolGuid,
+      {{
+        (PCH_SMM_GENERIC_REGISTER) PchPiSmmCoreRegister,
+        (PCH_SMM_GENERIC_UNREGISTER) PchPiSmmCoreUnRegister
+      }}
+    },
+    {
+      PROTOCOL_SIGNATURE,
+      PeriodicTimerType,
+      &gEfiSmmPeriodicTimerDispatch2ProtocolGuid,
+      {{
+        (PCH_SMM_GENERIC_REGISTER) PchPiSmmCoreRegister,
+        (PCH_SMM_GENERIC_UNREGISTER) PchPiSmmCoreUnRegister,
+        (UINTN) PchSmmPeriodicTimerDispatchGetNextShorterInterval
+      }}
+    },
+  }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONTEXT_FUNCTIONS     mContextFunctions[PCH_SMM_PROTOCOL_TYPE_MAX] = {
+  {
+    NULL,
+    NULL,
+    NULL
+  },
+  {
+    SxGetContext,
+    SxCmpContext,
+    NULL
+  },
+  {
+    NULL,
+    NULL,
+    NULL
+  },
+  {
+    NULL,
+    NULL,
+    NULL
+  },
+  {
+    PowerButtonGetContext,
+    PowerButtonCmpContext,
+    NULL
+  },
+  {
+    PeriodicTimerGetContext,
+    PeriodicTimerCmpContext,
+    PeriodicTimerGetCommBuffer
+  },
+};
+
+//
+// PROTOTYPES
+//
+// Functions use only in this file
+//
+EFI_STATUS
+EFIAPI
+PchSmmCoreDispatcher (
+  IN       EFI_HANDLE         SmmImageHandle,
+  IN CONST VOID               *PchSmmCore,     OPTIONAL
+  IN OUT   VOID               *CommunicationBuffer,
+  IN OUT   UINTN              *SourceSize
+  );
+
+//
+// FUNCTIONS
+//
+/**
+  SMM ready to lock notification event handler.
+
+  @param  Protocol   Points to the protocol's unique identifier
+  @param  Interface  Points to the interface instance
+  @param  Handle     The handle on which the interface was installed
+
+  @retval EFI_SUCCESS   SmmReadyToLockCallback runs successfully
+
+**/
+EFI_STATUS
+EFIAPI
+SmmReadyToLockCallback (
+  IN CONST EFI_GUID                       *Protocol,
+  IN VOID                                 *Interface,
+  IN EFI_HANDLE                           Handle
+  )
+{
+  mReadyToLock = TRUE;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  <b>PchSmiDispatcher SMM Module Entry Point</b>\n
+  - <b>Introduction</b>\n
+    The PchSmiDispatcher module is an SMM driver which  provides SMI handler registration
+    services for PCH generated SMIs.
+
+  - <b>Details</b>\n
+    This module provides SMI handler registration servicies for PCH SMIs.
+    NOTE: All the register/unregister functions will be locked after SMM ready to boot signal event.
+    Please make sure no handler is installed after that.
+
+  - @pre
+    - EFI_SMM_BASE2_PROTOCOL
+      - Documented in the System Management Mode Core Interface Specification
+    - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+      - Documented in the UEFI 2.0 Specification and above
+    - EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+      - This is to ensure that PCI MMIO and IO resource has been prepared and available for this driver to allocate.
+    - EFI_SMM_CPU_PROTOCOL
+
+  - @result
+    The PchSmiDispatcher driver produces:
+    - EFI_SMM_USB_DISPATCH2_PROTOCOL
+    - EFI_SMM_SX_DISPATCH2_PROTOCOL
+    - EFI_SMM_SW_DISPATCH2_PROTOCOL
+    - EFI_SMM_GPI_DISPATCH2_PROTOCOL
+    - EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL
+    - EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL
+    - EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL
+    - @link _PCH_SMM_IO_TRAP_CONTROL_PROTOCOL PCH_SMM_IO_TRAP_CONTROL_PROTOCOL @endlink
+    - @link _PCH_PCIE_SMI_DISPATCH_PROTOCOL PCH_PCIE_SMI_DISPATCH_PROTOCOL @endlink
+    - @link _PCH_TCO_SMI_DISPATCH_PROTOCOL PCH_TCO_SMI_DISPATCH_PROTOCOL @endlink
+    - @link _PCH_ACPI_SMI_DISPATCH_PROTOCOL PCH_ACPI_SMI_DISPATCH_PROTOCOL @endlink
+    - @link _PCH_SMI_DISPATCH_PROTOCOL PCH_SMI_DISPATCH_PROTOCOL @endlink
+    - @link _PCH_ESPI_SMI_DISPATCH_PROTOCOL PCH_ESPI_SMI_DISPATCH_PROTOCOL @endlink
+
+  @param[in] ImageHandle          Pointer to the loaded image protocol for this driver
+  @param[in] SystemTable          Pointer to the EFI System Table
+
+  @retval EFI_SUCCESS             PchSmmDispatcher Initialization completed.
+**/
+EFI_STATUS
+EFIAPI
+InitializePchSmmDispatcher (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS           Status;
+  VOID                 *SmmReadyToLockRegistration;
+
+  mS3SusStart = FALSE;
+  //
+  // Access ACPI Base Addresses Register
+  //
+
+  mAcpiBaseAddr = PmcGetAcpiBase ();
+  ASSERT (mAcpiBaseAddr != 0);
+
+  //
+  // Access TCO Base Addresses Register
+  //
+  PchTcoBaseGet (&mTcoBaseAddr);
+  ASSERT (mTcoBaseAddr != 0);
+
+  //
+  // Register a callback function to handle subsequent SMIs.  This callback
+  // will be called by SmmCoreDispatcher.
+  //
+  Status = gSmst->SmiHandlerRegister (PchSmmCoreDispatcher, NULL, &mPrivateData.SmiHandle);
+  ASSERT_EFI_ERROR (Status);
+  //
+  // Initialize Callback DataBase
+  //
+  InitializeListHead (&mPrivateData.CallbackDataBase);
+
+  //
+  // Enable SMIs on the PCH now that we have a callback
+  //
+  PchSmmInitHardware ();
+
+  //
+  // Install and initialize all the needed protocols
+  //
+  PchSwDispatchInit ();
+  PchSmmPublishDispatchProtocols ();
+  InstallPchSmiDispatchProtocols ();
+  InstallIoTrap (ImageHandle);
+  InstallEspiSmi (ImageHandle);
+  InstallPchSmmPeriodicTimerControlProtocol (mPrivateData.InstallMultProtHandle);
+
+  //
+  // Register EFI_SMM_READY_TO_LOCK_PROTOCOL_GUID notify function.
+  //
+  Status = gSmst->SmmRegisterProtocolNotify (
+                    &gEfiSmmReadyToLockProtocolGuid,
+                    SmmReadyToLockCallback,
+                    &SmmReadyToLockRegistration
+                    );
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  The internal function used to create and insert a database record
+
+  @param[in]  InsertRecord              Record to insert to database.
+  @param[out] DispatchHandle            Handle of dispatch function to register.
+
+  @retval EFI_INVALID_PARAMETER         Error with NULL SMI source description
+  @retval EFI_OUT_OF_RESOURCES          Fail to allocate pool for database record
+  @retval EFI_SUCCESS                   The database record is created successfully.
+**/
+EFI_STATUS
+SmmCoreInsertRecord (
+  IN  DATABASE_RECORD                   *NewRecord,
+  OUT EFI_HANDLE                        *DispatchHandle
+  )
+{
+  EFI_STATUS                            Status;
+  DATABASE_RECORD                       *Record;
+
+  if ((NewRecord == NULL) ||
+      (NewRecord->Signature != DATABASE_RECORD_SIGNATURE))
+  {
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = gSmst->SmmAllocatePool (EfiRuntimeServicesData, sizeof (DATABASE_RECORD), (VOID **) &Record);
+  if (EFI_ERROR (Status)) {
+    ASSERT (FALSE);
+    return EFI_OUT_OF_RESOURCES;
+  }
+  CopyMem (Record, NewRecord, sizeof (DATABASE_RECORD));
+
+  //
+  // After ensuring the source of event is not null, we will insert the record into the database
+  //
+  InsertTailList (&mPrivateData.CallbackDataBase, &Record->Link);
+
+  //
+  // Child's handle will be the address linked list link in the record
+  //
+  *DispatchHandle = (EFI_HANDLE) (&Record->Link);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Unregister a child SMI source dispatch function with a parent SMM driver
+
+  @param[in] This                       Protocol instance pointer.
+  @param[in] DispatchHandle             Handle of dispatch function to deregister.
+
+  @retval EFI_SUCCESS                   The dispatch function has been successfully
+                                        unregistered and the SMI source has been disabled
+                                        if there are no other registered child dispatch
+                                        functions for this SMI source.
+  @retval EFI_INVALID_PARAMETER         Handle is invalid.
+  @retval EFI_ACCESS_DENIED             Return access denied if the SmmReadyToLock event has been triggered
+**/
+EFI_STATUS
+EFIAPI
+PchPiSmmCoreUnRegister (
+  IN PCH_SMM_GENERIC_PROTOCOL                           *This,
+  IN EFI_HANDLE                                         *DispatchHandle
+  )
+{
+  DATABASE_RECORD                   *RecordToDelete;
+  EFI_STATUS                        Status;
+  PCH_SMM_QUALIFIED_PROTOCOL        *Qualified;
+
+  Qualified      = QUALIFIED_PROTOCOL_FROM_GENERIC (This);
+  RecordToDelete = DATABASE_RECORD_FROM_LINK (DispatchHandle);
+  Status         = PchSmmCoreUnRegister (NULL, DispatchHandle);
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileUnregisterHandler (
+      Qualified->Guid,
+      RecordToDelete->Callback,
+      &RecordToDelete->ChildContext,
+      RecordToDelete->ContextSize
+      );
+  }
+  return Status;
+}
+
+/**
+  Register a child SMI dispatch function with a parent SMM driver.
+
+  @param[in] This                 Pointer to the PCH_SMM_GENERIC_PROTOCOL instance.
+  @param[in] DispatchFunction     Pointer to dispatch function to be invoked for this SMI source.
+  @param[in] DispatchContext      Pointer to the dispatch function's context.
+  @param[out] DispatchHandle      Handle of dispatch function, for when interfacing
+                                  with the parent SMM driver, will be the address of linked
+                                  list link in the call back record.
+
+  @retval EFI_OUT_OF_RESOURCES    Insufficient resources to create database record
+  @retval EFI_INVALID_PARAMETER   The input parameter is invalid
+  @retval EFI_SUCCESS             The dispatch function has been successfully
+                                  registered and the SMI source has been enabled.
+**/
+EFI_STATUS
+EFIAPI
+PchPiSmmCoreRegister (
+  IN  PCH_SMM_GENERIC_PROTOCOL                          *This,
+  IN  EFI_SMM_HANDLER_ENTRY_POINT2                      DispatchFunction,
+  IN  PCH_SMM_CONTEXT                                   *DispatchContext,
+  OUT EFI_HANDLE                                        *DispatchHandle
+  )
+{
+  EFI_STATUS                  Status;
+  DATABASE_RECORD             Record;
+  PCH_SMM_QUALIFIED_PROTOCOL  *Qualified;
+  PCH_SMM_SOURCE_DESC         NullSourceDesc;
+
+  //
+  // Initialize NullSourceDesc
+  //
+  NullInitSourceDesc (&NullSourceDesc);
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the EndOfDxe event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  ZeroMem (&Record, sizeof (DATABASE_RECORD));
+
+  //
+  // Gather information about the registration request
+  //
+  Record.Callback          = DispatchFunction;
+
+  Qualified                = QUALIFIED_PROTOCOL_FROM_GENERIC (This);
+
+  Record.ProtocolType      = Qualified->Type;
+
+  Record.ContextFunctions  = mContextFunctions[Qualified->Type];
+  //
+  // Perform linked list housekeeping
+  //
+  Record.Signature         = DATABASE_RECORD_SIGNATURE;
+
+  switch (Qualified->Type) {
+    //
+    // By the end of this switch statement, we'll know the
+    // source description the child is registering for
+    //
+    case UsbType:
+      Record.ContextSize = sizeof (EFI_SMM_USB_REGISTER_CONTEXT);
+      CopyMem (&Record.ChildContext, DispatchContext, Record.ContextSize);
+      //
+      // Check the validity of Context Type
+      //
+      if ((Record.ChildContext.Usb.Type < UsbLegacy) || (Record.ChildContext.Usb.Type > UsbWake)) {
+        return EFI_INVALID_PARAMETER;
+      }
+
+      MapUsbToSrcDesc (DispatchContext, &Record.SrcDesc);
+      Record.ClearSource = NULL;
+      //
+      // use default clear source function
+      //
+      break;
+
+    case SxType:
+      Record.ContextSize = sizeof (EFI_SMM_SX_REGISTER_CONTEXT);
+      CopyMem (&Record.ChildContext, DispatchContext, Record.ContextSize);
+      //
+      // Check the validity of Context Type and Phase
+      //
+      if ((Record.ChildContext.Sx.Type < SxS0) ||
+          (Record.ChildContext.Sx.Type >= EfiMaximumSleepType) ||
+          (Record.ChildContext.Sx.Phase < SxEntry) ||
+          (Record.ChildContext.Sx.Phase >= EfiMaximumPhase)
+          ) {
+        return EFI_INVALID_PARAMETER;
+      }
+
+      CopyMem (&Record.SrcDesc, &mSxSourceDesc, sizeof (PCH_SMM_SOURCE_DESC));
+      Record.ClearSource = NULL;
+      //
+      // use default clear source function
+      //
+      break;
+
+    case PowerButtonType:
+      Record.ContextSize = sizeof (EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT);
+      CopyMem (&Record.ChildContext, DispatchContext, Record.ContextSize);
+      //
+      // Check the validity of Context Phase
+      //
+      if ((Record.ChildContext.PowerButton.Phase < EfiPowerButtonEntry) ||
+          (Record.ChildContext.PowerButton.Phase > EfiPowerButtonExit))
+      {
+        return EFI_INVALID_PARAMETER;
+      }
+
+      CopyMem (&Record.SrcDesc, &mPowerButtonSourceDesc, sizeof (PCH_SMM_SOURCE_DESC));
+      Record.ClearSource = NULL;
+      //
+      // use default clear source function
+      //
+      break;
+
+    case PeriodicTimerType:
+      Record.ContextSize = sizeof (EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT);
+      CopyMem (&Record.ChildContext, DispatchContext, Record.ContextSize);
+      //
+      // Check the validity of timer value
+      //
+      if (DispatchContext->PeriodicTimer.SmiTickInterval <= 0) {
+        return EFI_INVALID_PARAMETER;
+      }
+
+      MapPeriodicTimerToSrcDesc (DispatchContext, &Record.SrcDesc);
+      Record.MiscData.TimerSmiEnabled = TRUE;
+      Record.ClearSource = PchSmmPeriodicTimerClearSource;
+      break;
+
+    default:
+      return EFI_INVALID_PARAMETER;
+      break;
+  }
+
+  if (CompareSources (&Record.SrcDesc, &NullSourceDesc)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // After ensuring the source of event is not null, we will insert the record into the database
+  // Child's handle will be the address linked list link in the record
+  //
+  Status = SmmCoreInsertRecord (
+             &Record,
+             DispatchHandle
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  if (Record.ClearSource == NULL) {
+    //
+    // Clear the SMI associated w/ the source using the default function
+    //
+    PchSmmClearSource (&Record.SrcDesc);
+  } else {
+    //
+    // This source requires special handling to clear
+    //
+    Record.ClearSource (&Record.SrcDesc);
+  }
+
+  PchSmmEnableSource (&Record.SrcDesc);
+  SmiHandlerProfileRegisterHandler (
+    Qualified->Guid,
+    DispatchFunction,
+    (UINTN)RETURN_ADDRESS (0),
+    DispatchContext,
+    Record.ContextSize
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Unregister a child SMI source dispatch function with a parent SMM driver.
+
+  @param[in] This                 Pointer to the PCH_SMM_GENERIC_PROTOCOL instance.
+  @param[in] DispatchHandle       Handle of dispatch function to deregister.
+
+  @retval EFI_SUCCESS             The dispatch function has been successfully
+                                  unregistered and the SMI source has been disabled
+                                  if there are no other registered child dispatch
+                                  functions for this SMI source.
+  @retval EFI_INVALID_PARAMETER   Handle is invalid.
+**/
+EFI_STATUS
+EFIAPI
+PchSmmCoreUnRegister (
+  IN PCH_SMM_GENERIC_PROTOCOL                           *This,
+  IN EFI_HANDLE                                         *DispatchHandle
+  )
+{
+  EFI_STATUS                   Status;
+  BOOLEAN                      NeedClearEnable;
+  UINTN                        DescIndex;
+  DATABASE_RECORD              *RecordToDelete;
+  DATABASE_RECORD              *RecordInDb;
+  LIST_ENTRY                   *LinkInDb;
+
+  if (DispatchHandle == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "UnRegister is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  RecordToDelete = DATABASE_RECORD_FROM_LINK (DispatchHandle);
+
+  //
+  // Take the entry out of the linked list
+  //
+  if (RecordToDelete->Link.ForwardLink == (LIST_ENTRY *) EFI_BAD_POINTER) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  RemoveEntryList (&RecordToDelete->Link);
+
+  //
+  // Loop through all the souces in record linked list to see if any source enable is equal.
+  // If any source enable is equal, we do not want to disable it.
+  //
+  for (DescIndex = 0; DescIndex < NUM_EN_BITS; ++DescIndex) {
+    if (IS_BIT_DESC_NULL (RecordToDelete->SrcDesc.En[DescIndex])) {
+      continue;
+    }
+    NeedClearEnable = TRUE;
+    LinkInDb = GetFirstNode (&mPrivateData.CallbackDataBase);
+    while (!IsNull (&mPrivateData.CallbackDataBase, LinkInDb)) {
+      RecordInDb = DATABASE_RECORD_FROM_LINK (LinkInDb);
+      if (IsBitEqualToAnySourceEn (&RecordToDelete->SrcDesc.En[DescIndex], &RecordInDb->SrcDesc)) {
+        NeedClearEnable = FALSE;
+        break;
+      }
+      LinkInDb = GetNextNode (&mPrivateData.CallbackDataBase, &RecordInDb->Link);
+    }
+    if (NeedClearEnable == FALSE) {
+      continue;
+    }
+    WriteBitDesc (&RecordToDelete->SrcDesc.En[DescIndex], 0, FALSE);
+  }
+  Status = gSmst->SmmFreePool (RecordToDelete);
+  if (EFI_ERROR (Status)) {
+    ASSERT (FALSE);
+    return Status;
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This function clears the pending SMI status before set EOS.
+  NOTE: This only clears the pending SMI with known reason.
+        Please do not clear unknown pending SMI status since that will hide potential issues.
+
+  @param[in] SmiStsValue                SMI status
+  @param[in] SciEn                      Sci Enable status
+**/
+STATIC
+VOID
+ClearPendingSmiStatus (
+  UINT32  SmiStsValue,
+  BOOLEAN SciEn
+  )
+{
+  //
+  // Clear NewCentury status if it's not handled.
+  //
+  if (SmiStsValue & B_ACPI_IO_SMI_STS_TCO) {
+    if (IoRead16 (mTcoBaseAddr + R_TCO_IO_TCO1_STS) & B_TCO_IO_TCO1_STS_NEWCENTURY) {
+      PchTcoSmiClearSourceAndBlock (&mSrcDescNewCentury);
+    }
+  }
+  // Clear PWRBTNOR_STS if it's not handled.
+  //
+  if (IoRead16 (mAcpiBaseAddr + R_ACPI_IO_PM1_STS) & B_ACPI_IO_PM1_STS_PRBTNOR) {
+    IoWrite16 (mAcpiBaseAddr + R_ACPI_IO_PM1_STS, B_ACPI_IO_PM1_STS_PRBTNOR);
+  }
+  //
+  // Clear WADT_STS if this is triggered by WADT timer.
+  //
+  if (!SciEn) {
+    if (IoRead32 (mAcpiBaseAddr + R_ACPI_IO_GPE0_STS_127_96) & B_ACPI_IO_GPE0_STS_127_96_WADT) {
+      IoWrite32 (mAcpiBaseAddr + R_ACPI_IO_GPE0_STS_127_96, B_ACPI_IO_GPE0_STS_127_96_WADT);
+    }
+  }
+  //
+  // Clear GPIO_UNLOCK_SMI_STS in case it is set as GPIO Unlock SMI is not supported
+  //
+  if (SmiStsValue & B_ACPI_IO_SMI_STS_GPIO_UNLOCK) {
+    IoWrite32 (mAcpiBaseAddr + R_ACPI_IO_SMI_STS, B_ACPI_IO_SMI_STS_GPIO_UNLOCK);
+  }
+}
+
+/**
+  The callback function to handle subsequent SMIs.  This callback will be called by SmmCoreDispatcher.
+
+  @param[in] SmmImageHandle             Not used
+  @param[in] PchSmmCore                 Not used
+  @param[in, out] CommunicationBuffer   Not used
+  @param[in, out] SourceSize            Not used
+
+  @retval EFI_SUCCESS                   Function successfully completed
+**/
+EFI_STATUS
+EFIAPI
+PchSmmCoreDispatcher (
+  IN       EFI_HANDLE         SmmImageHandle,
+  IN CONST VOID               *PchSmmCore,
+  IN OUT   VOID               *CommunicationBuffer,
+  IN OUT   UINTN              *SourceSize
+  )
+{
+  //
+  // Used to prevent infinite loops
+  //
+  UINTN               EscapeCount;
+
+  BOOLEAN             ContextsMatch;
+  BOOLEAN             EosSet;
+  BOOLEAN             SxChildWasDispatched;
+
+  DATABASE_RECORD     *RecordInDb;
+  LIST_ENTRY          *LinkInDb;
+  DATABASE_RECORD     *RecordToExhaust;
+  LIST_ENTRY          *LinkToExhaust;
+
+  PCH_SMM_CONTEXT     Context;
+  VOID                *CommBuffer;
+  UINTN               CommBufferSize;
+
+  EFI_STATUS          Status;
+  BOOLEAN             SciEn;
+  UINT32              SmiEnValue;
+  UINT32              SmiStsValue;
+  UINT8               Port74Save;
+  UINT8               Port76Save;
+
+  PCH_SMM_SOURCE_DESC ActiveSource;
+
+  //
+  // Initialize ActiveSource
+  //
+  NullInitSourceDesc (&ActiveSource);
+
+  EscapeCount           = 3;
+  ContextsMatch         = FALSE;
+  EosSet                = FALSE;
+  SxChildWasDispatched  = FALSE;
+  Status                = EFI_SUCCESS;
+
+  //
+  // Save IO index registers
+  // @note: Save/Restore port 70h directly might break NMI_EN# setting,
+  //       then save/restore 74h/76h instead.
+  // @note: CF8 is not saved. Prefer method is to use MMIO instead of CF8
+  //
+  Port76Save = IoRead8 (R_RTC_IO_EXT_INDEX_ALT);
+  Port74Save = IoRead8 (R_RTC_IO_INDEX_ALT);
+
+  if (!IsListEmpty (&mPrivateData.CallbackDataBase)) {
+    //
+    // We have children registered w/ us -- continue
+    //
+    while ((!EosSet) && (EscapeCount > 0)) {
+      EscapeCount--;
+
+      LinkInDb = GetFirstNode (&mPrivateData.CallbackDataBase);
+
+      //
+      // Cache SciEn, SmiEnValue and SmiStsValue to determine if source is active
+      //
+      SciEn       = PchSmmGetSciEn ();
+      SmiEnValue  = IoRead32 ((UINTN) (mAcpiBaseAddr + R_ACPI_IO_SMI_EN));
+      SmiStsValue = IoRead32 ((UINTN) (mAcpiBaseAddr + R_ACPI_IO_SMI_STS));
+
+      while (!IsNull (&mPrivateData.CallbackDataBase, LinkInDb)) {
+        RecordInDb = DATABASE_RECORD_FROM_LINK (LinkInDb);
+
+        //
+        // look for the first active source
+        //
+        if (!SourceIsActive (&RecordInDb->SrcDesc, SciEn, SmiEnValue, SmiStsValue)) {
+          //
+          // Didn't find the source yet, keep looking
+          //
+          LinkInDb = GetNextNode (&mPrivateData.CallbackDataBase, &RecordInDb->Link);
+
+          //
+          // if it's the last one, try to clear EOS
+          //
+          if (IsNull (&mPrivateData.CallbackDataBase, LinkInDb)) {
+            //
+            // Clear pending SMI status before EOS
+            //
+            ClearPendingSmiStatus (SmiStsValue, SciEn);
+            EosSet = PchSmmSetAndCheckEos ();
+          }
+        } else {
+          //
+          // We found a source. If this is a sleep type, we have to go to
+          // appropriate sleep state anyway.No matter there is sleep child or not
+          //
+          if (RecordInDb->ProtocolType == SxType) {
+            SxChildWasDispatched = TRUE;
+          }
+          //
+          // "cache" the source description and don't query I/O anymore
+          //
+          CopyMem ((VOID *) &ActiveSource, (VOID *) &(RecordInDb->SrcDesc), sizeof (PCH_SMM_SOURCE_DESC));
+          LinkToExhaust = LinkInDb;
+
+          //
+          // exhaust the rest of the queue looking for the same source
+          //
+          while (!IsNull (&mPrivateData.CallbackDataBase, LinkToExhaust)) {
+            RecordToExhaust = DATABASE_RECORD_FROM_LINK (LinkToExhaust);
+            //
+            // RecordToExhaust->Link might be removed (unregistered) by Callback function, and then the
+            // system will hang in ASSERT() while calling GetNextNode().
+            // To prevent the issue, we need to get next record in DB here (before Callback function).
+            //
+            LinkToExhaust = GetNextNode (&mPrivateData.CallbackDataBase, &RecordToExhaust->Link);
+
+            if (CompareSources (&RecordToExhaust->SrcDesc, &ActiveSource)) {
+              //
+              // These source descriptions are equal, so this callback should be
+              // dispatched.
+              //
+              if (RecordToExhaust->ContextFunctions.GetContext != NULL) {
+                //
+                // This child requires that we get a calling context from
+                // hardware and compare that context to the one supplied
+                // by the child.
+                //
+                ASSERT (RecordToExhaust->ContextFunctions.CmpContext != NULL);
+
+                //
+                // Make sure contexts match before dispatching event to child
+                //
+                RecordToExhaust->ContextFunctions.GetContext (RecordToExhaust, &Context);
+                ContextsMatch = RecordToExhaust->ContextFunctions.CmpContext (&Context, &RecordToExhaust->ChildContext);
+
+              } else {
+                //
+                // This child doesn't require any more calling context beyond what
+                // it supplied in registration.  Simply pass back what it gave us.
+                //
+                Context       = RecordToExhaust->ChildContext;
+                ContextsMatch = TRUE;
+              }
+
+              if (ContextsMatch) {
+                if (RecordToExhaust->ProtocolType == PchSmiDispatchType) {
+                  //
+                  // For PCH SMI dispatch protocols
+                  //
+                  PchSmiTypeCallbackDispatcher (RecordToExhaust);
+                } else {
+                  if ((RecordToExhaust->ProtocolType == SxType) && (Context.Sx.Type == SxS3) && (Context.Sx.Phase == SxEntry) && !mS3SusStart) {
+                    REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PROGRESS_CODE_S3_SUSPEND_START);
+                    mS3SusStart = TRUE;
+                  }
+                  //
+                  // For EFI standard SMI dispatch protocols
+                  //
+                  if (RecordToExhaust->Callback != NULL) {
+                    if (RecordToExhaust->ContextFunctions.GetCommBuffer != NULL) {
+                      //
+                      // This callback function needs CommBuffer and CommBufferSize.
+                      // Get those from child and then pass to callback function.
+                      //
+                      RecordToExhaust->ContextFunctions.GetCommBuffer (RecordToExhaust, &CommBuffer, &CommBufferSize);
+                    } else {
+                      //
+                      // Child doesn't support the CommBuffer and CommBufferSize.
+                      // Just pass NULL value to callback function.
+                      //
+                      CommBuffer     = NULL;
+                      CommBufferSize = 0;
+                    }
+
+                    PERF_START_EX (NULL, "SmmFunction", NULL, AsmReadTsc (), RecordToExhaust->ProtocolType);
+                    RecordToExhaust->Callback ((EFI_HANDLE) & RecordToExhaust->Link, &Context, CommBuffer, &CommBufferSize);
+                    PERF_END_EX (NULL, "SmmFunction", NULL, AsmReadTsc (), RecordToExhaust->ProtocolType);
+                    if (RecordToExhaust->ProtocolType == SxType) {
+                      SxChildWasDispatched = TRUE;
+                    }
+                  } else {
+                    ASSERT (FALSE);
+                  }
+                }
+              }
+            }
+          }
+
+          if (RecordInDb->ClearSource == NULL) {
+            //
+            // Clear the SMI associated w/ the source using the default function
+            //
+            PchSmmClearSource (&ActiveSource);
+          } else {
+            //
+            // This source requires special handling to clear
+            //
+            RecordInDb->ClearSource (&ActiveSource);
+          }
+          //
+          // Clear pending SMI status before EOS
+          //
+          ClearPendingSmiStatus (SmiStsValue, SciEn);
+          //
+          // Also, try to clear EOS
+          //
+          EosSet = PchSmmSetAndCheckEos ();
+          //
+          // Queue is empty, reset the search
+          //
+          break;
+        }
+      }
+    }
+  }
+  //
+  // If you arrive here, there are two possible reasons:
+  // (1) you've got problems with clearing the SMI status bits in the
+  // ACPI table.  If you don't properly clear the SMI bits, then you won't be able to set the
+  // EOS bit.  If this happens too many times, the loop exits.
+  // (2) there was a SMM communicate for callback messages that was received prior
+  // to this driver.
+  // If there is an asynchronous SMI that occurs while processing the Callback, let
+  // all of the drivers (including this one) have an opportunity to scan for the SMI
+  // and handle it.
+  // If not, we don't want to exit and have the foreground app. clear EOS without letting
+  // these other sources get serviced.
+  //
+  // This assert is not valid with CSM legacy solution because it generates software SMI
+  // to test for legacy USB support presence.
+  // This may not be illegal, so we cannot assert at this time.
+  //
+  //  ASSERT (EscapeCount > 0);
+  //
+  if (SxChildWasDispatched) {
+    //
+    // A child of the SmmSxDispatch protocol was dispatched during this call;
+    // put the system to sleep.
+    //
+    PchSmmSxGoToSleep ();
+  }
+  //
+  // Restore IO index registers
+  // @note: Save/Restore port 70h directly might break NMI_EN# setting,
+  //       then save/restore 74h/76h instead.
+  //
+  IoWrite8 (R_RTC_IO_EXT_INDEX_ALT, Port76Save);
+  IoWrite8 (R_RTC_IO_INDEX_ALT, Port74Save);
+
+  return Status;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.c
new file mode 100644
index 0000000000..9ce4072e37
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.c
@@ -0,0 +1,1588 @@
+/** @file
+  eSPI SMI implementation
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchSmmEspi.h"
+#include <Library/PmcPrivateLib.h>
+#include <Library/EspiLib.h>
+#include <Library/SmiHandlerProfileLib.h>
+#include <Register/PchRegs.h>
+#include <Register/PchPcrRegs.h>
+#include <Register/PchRegsLpc.h>
+#include <Library/PchPciBdfLib.h>
+#include <PchBdfAssignment.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED ESPI_SMI_INSTANCE mEspiSmiInstance = {
+  //
+  // Signature
+  //
+  ESPI_SMI_INSTANCE_SIGNATURE,
+  //
+  // Handle
+  //
+  NULL,
+  //
+  // PchEspiSmiDispatchProtocol
+  //
+  {
+    PCH_ESPI_SMI_DISPATCH_REVISION,
+    EspiSmiUnRegister,
+    BiosWrProtectRegister,
+    BiosWrReportRegister,
+    PcNonFatalErrRegister,
+    PcFatalErrRegister,
+    VwNonFatalErrRegister,
+    VwFatalErrRegister,
+    FlashNonFatalErrRegister,
+    FlashFatalErrRegister,
+    LnkType1ErrRegister,
+    EspiSlaveSmiRegister
+  },
+  //
+  // PchSmiEspiHandle[EspiTopLevelTypeMax]
+  //
+  {
+    NULL, NULL, NULL
+  },
+  //
+  // CallbackDataBase[EspiSmiTypeMax]
+  //
+  {
+    {NULL, NULL}, {NULL, NULL}, {NULL, NULL}, {NULL, NULL}, {NULL, NULL},
+    {NULL, NULL}, {NULL, NULL}, {NULL, NULL}, {NULL, NULL}, {NULL, NULL}
+  },
+  //
+  // EspiSmiEventCounter[EspiSmiTypeMax]
+  //
+  {
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  //
+  // Barrier[EspiTopLevelTypeMax]
+  //
+  {
+    {
+      BiosWrProtect,
+      BiosWrProtect
+    },
+    {
+      BiosWrReport,
+      LnkType1Err
+    },
+    {
+      EspiSlaveSmi,
+      EspiSlaveSmi
+    }
+  }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST ESPI_DESCRIPTOR mEspiDescriptor[EspiSmiTypeMax] = {
+  //
+  // BiosWrProtect
+  //
+  {
+    {
+      PCIE_ADDR_TYPE,
+      { (
+        (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+        (PCI_DEVICE_NUMBER_PCH_LPC << 19) |
+        (PCI_FUNCTION_NUMBER_PCH_LPC << 16) |
+        R_ESPI_CFG_PCBC
+      ) }
+    },
+    //
+    // SourceIsActiveAndMask and SourceIsActiveValue
+    //
+    B_ESPI_CFG_PCBC_BWPDS | B_ESPI_CFG_PCBC_LE,
+    B_ESPI_CFG_PCBC_BWPDS | B_ESPI_CFG_PCBC_LE,
+    //
+    // ClearStatusAndMask and ClearStatusOrMask
+    //
+    (UINT32) ~B_ESPI_CFG_PCBC_BWRS,
+    B_ESPI_CFG_PCBC_BWPDS
+  },
+  //
+  // BiosWrReport
+  //
+  {
+    {
+      PCIE_ADDR_TYPE,
+      { (
+        (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+        (PCI_DEVICE_NUMBER_PCH_LPC << 19) |
+        (PCI_FUNCTION_NUMBER_PCH_LPC << 16) |
+        R_ESPI_CFG_PCBC
+      ) }
+    },
+    B_ESPI_CFG_PCBC_BWRS | B_ESPI_CFG_PCBC_BWRE,
+    B_ESPI_CFG_PCBC_BWRS | B_ESPI_CFG_PCBC_BWRE,
+    (UINT32) ~B_ESPI_CFG_PCBC_BWPDS,
+    B_ESPI_CFG_PCBC_BWRS
+  },
+  //
+  // PcNonFatalErr
+  //
+  {
+    {
+      PCR_ADDR_TYPE,
+      {PCH_PCR_ADDRESS (PID_ESPISPI, R_ESPI_PCR_PCERR_SLV0) }
+    },
+    (B_ESPI_PCR_XERR_XNFES | B_ESPI_PCR_XERR_XNFEE),
+    (B_ESPI_PCR_XERR_XNFES | (V_ESPI_PCR_XERR_XNFEE_SMI << N_ESPI_PCR_XERR_XNFEE)),
+    (UINT32) ~(B_ESPI_PCR_PCERR_SLV0_PCURD | B_ESPI_PCR_XERR_XFES),
+    B_ESPI_PCR_XERR_XNFES
+  },
+  //
+  // PcFatalErr
+  //
+  {
+    {
+      PCR_ADDR_TYPE,
+      {PCH_PCR_ADDRESS (PID_ESPISPI, R_ESPI_PCR_PCERR_SLV0) }
+    },
+    (B_ESPI_PCR_XERR_XFES | B_ESPI_PCR_XERR_XFEE),
+    (B_ESPI_PCR_XERR_XFES | (V_ESPI_PCR_XERR_XFEE_SMI << N_ESPI_PCR_XERR_XFEE)),
+    (UINT32) ~(B_ESPI_PCR_PCERR_SLV0_PCURD | B_ESPI_PCR_XERR_XNFES),
+    B_ESPI_PCR_XERR_XFES
+  },
+  //
+  // VwNonFatalErr
+  //
+  {
+    {
+      PCR_ADDR_TYPE,
+      {PCH_PCR_ADDRESS (PID_ESPISPI, R_ESPI_PCR_VWERR_SLV0) }
+    },
+    (B_ESPI_PCR_XERR_XNFES | B_ESPI_PCR_XERR_XNFEE),
+    (B_ESPI_PCR_XERR_XNFES | (V_ESPI_PCR_XERR_XNFEE_SMI << N_ESPI_PCR_XERR_XNFEE)),
+    (UINT32) ~B_ESPI_PCR_XERR_XFES,
+    B_ESPI_PCR_XERR_XNFES
+  },
+  //
+  // VwFatalErr
+  //
+  {
+    {
+      PCR_ADDR_TYPE,
+      {PCH_PCR_ADDRESS (PID_ESPISPI, R_ESPI_PCR_VWERR_SLV0) }
+    },
+    (B_ESPI_PCR_XERR_XFES | B_ESPI_PCR_XERR_XFEE),
+    (B_ESPI_PCR_XERR_XFES | (V_ESPI_PCR_XERR_XFEE_SMI << N_ESPI_PCR_XERR_XFEE)),
+    (UINT32) ~B_ESPI_PCR_XERR_XNFES,
+    B_ESPI_PCR_XERR_XFES
+  },
+  //
+  // FlashNonFatalErr
+  //
+  {
+    {
+      PCR_ADDR_TYPE,
+      {PCH_PCR_ADDRESS (PID_ESPISPI, R_ESPI_PCR_FCERR_SLV0) }
+    },
+    (B_ESPI_PCR_XERR_XNFES | B_ESPI_PCR_XERR_XNFEE),
+    (B_ESPI_PCR_XERR_XNFES | (V_ESPI_PCR_XERR_XNFEE_SMI << N_ESPI_PCR_XERR_XNFEE)),
+    (UINT32) ~B_ESPI_PCR_XERR_XFES,
+    B_ESPI_PCR_XERR_XNFES
+  },
+  //
+  // FlashFatalErr
+  //
+  {
+    {
+      PCR_ADDR_TYPE,
+      {PCH_PCR_ADDRESS (PID_ESPISPI, R_ESPI_PCR_FCERR_SLV0) }
+    },
+    (B_ESPI_PCR_XERR_XFES | B_ESPI_PCR_XERR_XFEE),
+    (B_ESPI_PCR_XERR_XFES | (V_ESPI_PCR_XERR_XFEE_SMI << N_ESPI_PCR_XERR_XFEE)),
+    (UINT32) ~B_ESPI_PCR_XERR_XNFES,
+    B_ESPI_PCR_XERR_XFES
+  },
+  //
+  // LnkType1Err
+  //
+  {
+    {
+      PCR_ADDR_TYPE,
+      {PCH_PCR_ADDRESS (PID_ESPISPI, R_ESPI_PCR_LNKERR_SLV0) }
+    },
+    B_ESPI_PCR_LNKERR_SLV0_LFET1S | B_ESPI_PCR_LNKERR_SLV0_LFET1E,
+    B_ESPI_PCR_LNKERR_SLV0_LFET1S | (V_ESPI_PCR_LNKERR_SLV0_LFET1E_SMI << N_ESPI_PCR_LNKERR_SLV0_LFET1E),
+    (UINT32) ~B_ESPI_PCR_LNKERR_SLV0_SLCRR,
+    B_ESPI_PCR_LNKERR_SLV0_LFET1S
+  },
+};
+
+/**
+  Enable eSPI SMI source
+
+  @param[in]  EspiSmiType  Type based on ESPI_SMI_TYPE
+**/
+STATIC
+VOID
+EspiSmiEnableSource (
+  IN CONST  ESPI_SMI_TYPE EspiSmiType
+  )
+{
+  UINT64      PciBaseAddress;
+
+  switch (EspiSmiType) {
+    case BiosWrProtect:
+      //
+      // It doesn't enable the BIOSLOCK here. Enable it by policy in DXE.
+      //
+      break;
+    case BiosWrReport:
+      PciBaseAddress = EspiPciCfgBase ();
+      PciSegmentAndThenOr32 (
+        PciBaseAddress + R_ESPI_CFG_PCBC,
+        (UINT32) ~(B_ESPI_CFG_PCBC_BWRS | B_ESPI_CFG_PCBC_BWPDS),
+        B_ESPI_CFG_PCBC_BWRE
+        );
+      break;
+    case PcNonFatalErr:
+      PchPcrAndThenOr32 (
+        PID_ESPISPI,
+        (UINT16) R_ESPI_PCR_PCERR_SLV0,
+        (UINT32) ~(B_ESPI_PCR_PCERR_SLV0_PCURD | B_ESPI_PCR_XERR_XNFES | B_ESPI_PCR_XERR_XFES),
+        B_ESPI_PCR_XERR_XNFEE
+        );
+      break;
+
+    case PcFatalErr:
+      PchPcrAndThenOr32 (
+        PID_ESPISPI,
+        (UINT16) R_ESPI_PCR_PCERR_SLV0,
+        (UINT32) ~(B_ESPI_PCR_PCERR_SLV0_PCURD | B_ESPI_PCR_XERR_XNFES | B_ESPI_PCR_XERR_XFES),
+        B_ESPI_PCR_XERR_XFEE
+        );
+      break;
+
+    case VwNonFatalErr:
+      PchPcrAndThenOr32 (
+        PID_ESPISPI,
+        (UINT16) R_ESPI_PCR_VWERR_SLV0,
+        (UINT32) ~(B_ESPI_PCR_XERR_XNFES | B_ESPI_PCR_XERR_XFES),
+        B_ESPI_PCR_XERR_XNFEE
+        );
+      break;
+
+    case VwFatalErr:
+      PchPcrAndThenOr32 (
+        PID_ESPISPI,
+        (UINT16) R_ESPI_PCR_VWERR_SLV0,
+        (UINT32) ~(B_ESPI_PCR_XERR_XNFES | B_ESPI_PCR_XERR_XFES),
+        B_ESPI_PCR_XERR_XFEE
+        );
+      break;
+
+    case FlashNonFatalErr:
+      PchPcrAndThenOr32 (
+        PID_ESPISPI,
+        (UINT16) R_ESPI_PCR_FCERR_SLV0,
+        (UINT32) ~(B_ESPI_PCR_XERR_XNFES | B_ESPI_PCR_XERR_XFES),
+        B_ESPI_PCR_XERR_XNFEE
+        );
+      break;
+
+    case FlashFatalErr:
+      PchPcrAndThenOr32 (
+        PID_ESPISPI,
+        (UINT16) R_ESPI_PCR_FCERR_SLV0,
+        (UINT32) ~(B_ESPI_PCR_XERR_XNFES | B_ESPI_PCR_XERR_XFES),
+        B_ESPI_PCR_XERR_XFEE
+        );
+      break;
+
+    case LnkType1Err:
+      PchPcrAndThenOr32 (
+        PID_ESPISPI,
+        (UINT16) R_ESPI_PCR_LNKERR_SLV0,
+        (UINT32) ~(B_ESPI_PCR_LNKERR_SLV0_SLCRR | B_ESPI_PCR_LNKERR_SLV0_LFET1S),
+        (UINT32) (V_ESPI_PCR_LNKERR_SLV0_LFET1E_SMI << N_ESPI_PCR_LNKERR_SLV0_LFET1E)
+        );
+
+      if (IsEspiSecondSlaveSupported ()) {
+        PchPcrAndThenOr32 (
+          PID_ESPISPI,
+          (UINT16) R_ESPI_PCR_LNKERR_SLV1,
+          (UINT32) ~(B_ESPI_PCR_LNKERR_SLV0_SLCRR | B_ESPI_PCR_LNKERR_SLV0_LFET1S),
+          (UINT32) (V_ESPI_PCR_LNKERR_SLV0_LFET1E_SMI << N_ESPI_PCR_LNKERR_SLV0_LFET1E)
+          );
+      }
+      break;
+
+    default:
+      DEBUG ((DEBUG_ERROR, "Unsupported EspiSmiType \n"));
+      ASSERT (FALSE);
+      break;
+  }
+}
+
+
+/**
+  Disable eSPI SMI source
+
+  @param[in]  EspiSmiType  Type based on ESPI_SMI_TYPE
+**/
+STATIC
+VOID
+EspiSmiDisableSource (
+  IN CONST  ESPI_SMI_TYPE EspiSmiType
+  )
+{
+
+  switch (EspiSmiType) {
+    case BiosWrProtect:
+    case BiosWrReport:
+      DEBUG ((DEBUG_ERROR, "Bit is write lock, thus BWRE/BWPDS source cannot be disabled \n"));
+      ASSERT (FALSE);
+      break;
+    case PcNonFatalErr:
+      PchPcrAndThenOr32 (
+        PID_ESPISPI,
+        (UINT16) R_ESPI_PCR_PCERR_SLV0,
+        (UINT32) ~(B_ESPI_PCR_PCERR_SLV0_PCURD | B_ESPI_PCR_XERR_XNFES | B_ESPI_PCR_XERR_XFES | B_ESPI_PCR_XERR_XNFEE),
+        0
+        );
+      break;
+
+    case PcFatalErr:
+      PchPcrAndThenOr32 (
+        PID_ESPISPI,
+        (UINT16) R_ESPI_PCR_PCERR_SLV0,
+        (UINT32) ~(B_ESPI_PCR_PCERR_SLV0_PCURD | B_ESPI_PCR_XERR_XNFES | B_ESPI_PCR_XERR_XFES | B_ESPI_PCR_XERR_XFEE),
+        0
+        );
+      break;
+
+    case VwNonFatalErr:
+      PchPcrAndThenOr32 (
+        PID_ESPISPI,
+        (UINT16) R_ESPI_PCR_VWERR_SLV0,
+        (UINT32) ~(B_ESPI_PCR_XERR_XNFES | B_ESPI_PCR_XERR_XFES | B_ESPI_PCR_XERR_XNFEE),
+        0
+        );
+      break;
+
+    case VwFatalErr:
+      PchPcrAndThenOr32 (
+        PID_ESPISPI,
+        (UINT16) R_ESPI_PCR_VWERR_SLV0,
+        (UINT32) ~(B_ESPI_PCR_XERR_XNFES | B_ESPI_PCR_XERR_XFES | B_ESPI_PCR_XERR_XFEE),
+        0
+        );
+      break;
+
+    case FlashNonFatalErr:
+      PchPcrAndThenOr32 (
+        PID_ESPISPI,
+        (UINT16) R_ESPI_PCR_FCERR_SLV0,
+        (UINT32) ~(B_ESPI_PCR_XERR_XNFES | B_ESPI_PCR_XERR_XFES | B_ESPI_PCR_XERR_XNFEE),
+        0
+        );
+      break;
+
+    case FlashFatalErr:
+      PchPcrAndThenOr32 (
+        PID_ESPISPI,
+       (UINT16) R_ESPI_PCR_FCERR_SLV0,
+       (UINT32) ~(B_ESPI_PCR_XERR_XNFES | B_ESPI_PCR_XERR_XFES | B_ESPI_PCR_XERR_XFEE),
+       0
+       );
+      break;
+
+    case LnkType1Err:
+      PchPcrAndThenOr32 (
+        PID_ESPISPI,
+        (UINT16) R_ESPI_PCR_LNKERR_SLV0,
+        (UINT32) ~(B_ESPI_PCR_LNKERR_SLV0_SLCRR | B_ESPI_PCR_LNKERR_SLV0_LFET1S),
+        0
+        );
+
+      if (IsEspiSecondSlaveSupported ()) {
+        PchPcrAndThenOr32 (
+          PID_ESPISPI,
+          (UINT16) R_ESPI_PCR_LNKERR_SLV1,
+          (UINT32) ~(B_ESPI_PCR_LNKERR_SLV0_SLCRR | B_ESPI_PCR_LNKERR_SLV0_LFET1S),
+          0
+          );
+      }
+      break;
+
+    default:
+      DEBUG ((DEBUG_ERROR, "Unsupported EspiSmiType \n"));
+      ASSERT (FALSE);
+      break;
+  }
+}
+
+/**
+  Clear a status for the SMI event
+
+  @param[in]  EspiSmiType  Type based on ESPI_SMI_TYPE
+**/
+STATIC
+VOID
+EspiSmiClearStatus (
+  IN CONST  ESPI_SMI_TYPE EspiSmiType
+  )
+{
+  UINT32                  PciBus;
+  UINT32                  PciDev;
+  UINT32                  PciFun;
+  UINT32                  PciReg;
+  UINT64                  PciBaseAddress;
+  CONST ESPI_DESCRIPTOR   *Desc;
+
+  Desc = &mEspiDescriptor[EspiSmiType];
+
+  switch (Desc->Address.Type) {
+    case PCIE_ADDR_TYPE:
+      PciBus  = Desc->Address.Data.pcie.Fields.Bus;
+      PciDev  = Desc->Address.Data.pcie.Fields.Dev;
+      PciFun  = Desc->Address.Data.pcie.Fields.Fnc;
+      PciReg  = Desc->Address.Data.pcie.Fields.Reg;
+      PciBaseAddress = PCI_SEGMENT_LIB_ADDRESS (DEFAULT_PCI_SEGMENT_NUMBER_PCH, PciBus, PciDev, PciFun, 0);
+      PciSegmentAndThenOr32 (PciBaseAddress + PciReg, Desc->ClearStatusAndMask, Desc->ClearStatusOrMask);
+      break;
+    case PCR_ADDR_TYPE:
+      PchPcrAndThenOr32 (
+        Desc->Address.Data.Pcr.Fields.Pid,
+        Desc->Address.Data.Pcr.Fields.Offset,
+        Desc->ClearStatusAndMask,
+        Desc->ClearStatusOrMask
+        );
+      break;
+    default:
+      DEBUG ((DEBUG_ERROR, "Address type for eSPI SMI is invalid \n"));
+      ASSERT (FALSE);
+      break;
+  }
+}
+
+/**
+  Checks if a source is active by looking at the enable and status bits
+
+  @param[in]  EspiSmiType  Type based on ESPI_SMI_TYPE
+**/
+STATIC
+BOOLEAN
+EspiSmiSourceIsActive (
+  IN CONST  ESPI_SMI_TYPE EspiSmiType
+  )
+{
+  BOOLEAN                 Active;
+  UINT32                  PciBus;
+  UINT32                  PciDev;
+  UINT32                  PciFun;
+  UINT32                  PciReg;
+  UINT64                  PciBaseAddress;
+  UINT32                  Data32;
+  CONST ESPI_DESCRIPTOR   *Desc;
+
+  Desc = &mEspiDescriptor[EspiSmiType];
+
+  Active = FALSE;
+  switch (Desc->Address.Type) {
+    case PCIE_ADDR_TYPE:
+      PciBus  = Desc->Address.Data.pcie.Fields.Bus;
+      PciDev  = Desc->Address.Data.pcie.Fields.Dev;
+      PciFun  = Desc->Address.Data.pcie.Fields.Fnc;
+      PciReg  = Desc->Address.Data.pcie.Fields.Reg;
+      PciBaseAddress = PCI_SEGMENT_LIB_ADDRESS (DEFAULT_PCI_SEGMENT_NUMBER_PCH, PciBus, PciDev, PciFun, 0);
+      Data32 = PciSegmentRead32 (PciBaseAddress + PciReg);
+      break;
+
+    case PCR_ADDR_TYPE:
+      Data32 = PchPcrRead32 (
+                 Desc->Address.Data.Pcr.Fields.Pid,
+                 Desc->Address.Data.Pcr.Fields.Offset
+                 );
+      break;
+
+    default:
+      Data32 = 0;
+      DEBUG ((DEBUG_ERROR, "Address type for eSPI SMI is invalid \n"));
+      ASSERT (FALSE);
+      break;
+  }
+
+  if ((Data32 & Desc->SourceIsActiveAndMask) == Desc->SourceIsActiveValue) {
+    Active = TRUE;
+  }
+
+  return Active;
+}
+
+/**
+  Insert a handler into the corresponding linked list based on EspiSmiType
+
+  @param[in]  DispatchFunction      The callback to execute
+  @param[in]  EspiSmiType           Type based on ESPI_SMI_TYPE to determine which linked list to use
+  @param[out] DispatchHandle        The link to the record in the database
+
+  @retval     EFI_SUCCESS           Record was successfully inserted into master database
+  @retval     EFI_OUT_OF_RESOURCES  Cannot allocate pool to insert record
+**/
+STATIC
+EFI_STATUS
+InsertEspiRecord (
+  IN        PCH_ESPI_SMI_DISPATCH_CALLBACK  DispatchFunction,
+  IN        ESPI_SMI_TYPE                   EspiSmiType,
+  OUT       EFI_HANDLE                      *DispatchHandle
+  )
+{
+  EFI_STATUS      Status;
+  ESPI_SMI_RECORD *Record;
+
+  Status = gSmst->SmmAllocatePool (EfiRuntimeServicesData, sizeof (ESPI_SMI_RECORD), (VOID **) &Record);
+  if (EFI_ERROR (Status)) {
+    ASSERT (FALSE);
+    return EFI_OUT_OF_RESOURCES;
+  }
+  SetMem (Record, sizeof (ESPI_SMI_RECORD), 0);
+
+  Record->Callback  = DispatchFunction;
+  Record->Signature = ESPI_SMI_RECORD_SIGNATURE;
+
+  InsertTailList (&mEspiSmiInstance.CallbackDataBase[EspiSmiType], &Record->Link);
+  EspiSmiClearStatus (EspiSmiType);
+  EspiSmiEnableSource (EspiSmiType);
+
+  ++mEspiSmiInstance.EspiSmiEventCounter[EspiSmiType];
+
+  *DispatchHandle = (EFI_HANDLE) (&Record->Link);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This callback is registered to PchSmiDispatch
+
+  @param[in]  DispatchHandle  Used to determine which source have been triggered
+**/
+VOID
+EspiSmiCallback (
+  IN  EFI_HANDLE                      DispatchHandle
+  )
+{
+  DATABASE_RECORD     *PchSmiRecord;
+  ESPI_TOP_LEVEL_TYPE EspiTopLevelType;
+  ESPI_SMI_TYPE       EspiSmiType;
+  ESPI_SMI_RECORD     *RecordInDb;
+  LIST_ENTRY          *LinkInDb;
+
+  PchSmiRecord = DATABASE_RECORD_FROM_LINK (DispatchHandle);
+
+  if (PchSmiRecord->PchSmiType == PchTcoSmiLpcBiosWpType) {
+    EspiTopLevelType = EspiBiosWrProtect;
+  } else if (PchSmiRecord->PchSmiType == PchSmiSerialIrqType) {
+    EspiTopLevelType = EspiSerialIrq;
+  } else {
+    DEBUG ((DEBUG_ERROR, "EspiSmiCallback was dispatched with a wrong DispatchHandle"));
+    ASSERT (FALSE);
+    return;
+  }
+
+  for (EspiSmiType = mEspiSmiInstance.Barrier[EspiTopLevelType].Start; EspiSmiType <= mEspiSmiInstance.Barrier[EspiTopLevelType].End; ++EspiSmiType) {
+    if (!EspiSmiSourceIsActive (EspiSmiType)) {
+      continue;
+    }
+    //
+    // The source is active, so walk the callback database and dispatch
+    //
+    if (!IsListEmpty (&mEspiSmiInstance.CallbackDataBase[EspiSmiType])) {
+      //
+      // We have children registered w/ us -- continue
+      //
+      LinkInDb = GetFirstNode (&mEspiSmiInstance.CallbackDataBase[EspiSmiType]);
+
+      while (!IsNull (&mEspiSmiInstance.CallbackDataBase[EspiSmiType], LinkInDb)) {
+        RecordInDb = ESPI_RECORD_FROM_LINK (LinkInDb);
+
+        //
+        // RecordInDb->Link might be removed (unregistered) by Callback function, and then the
+        // system will hang in ASSERT() while calling GetNextNode().
+        // To prevent the issue, we need to get next record in DB here (before Callback function).
+        //
+        LinkInDb = GetNextNode (&mEspiSmiInstance.CallbackDataBase[EspiSmiType], &RecordInDb->Link);
+
+        //
+        // Callback
+        //
+        if (RecordInDb->Callback != NULL) {
+          RecordInDb->Callback ((EFI_HANDLE) &RecordInDb->Link);
+        } else {
+          ASSERT (FALSE);
+        }
+      }
+    } else if (EspiSmiType == LnkType1Err) {
+      //
+      // If no proper handler registered for Link Type 1 Error
+      // Call default SMI handler recover otherwise
+      //
+      EspiDefaultFatalErrorHandler ();
+    }
+
+    //
+    // Finish walking the linked list for the EspiSmiType, so clear status
+    //
+    EspiSmiClearStatus (EspiSmiType);
+  }
+}
+
+//
+// EspiBiosWp srcdesc
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mSrcDescEspiBiosWp = {
+  PCH_SMM_NO_FLAGS,
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_EN}
+      },
+      S_ACPI_IO_SMI_EN,
+      N_ACPI_IO_SMI_EN_TCO
+    },
+    {
+      {
+        PCIE_ADDR_TYPE,
+        { (
+          (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+          (PCI_DEVICE_NUMBER_PCH_LPC << 19) |
+          (PCI_FUNCTION_NUMBER_PCH_LPC << 16) |
+          R_ESPI_CFG_PCBC
+        ) }
+      },
+      S_ESPI_CFG_PCBC,
+      N_ESPI_CFG_PCBC_LE
+    }
+  },
+  {
+    {
+      {
+        PCIE_ADDR_TYPE,
+        { (
+          (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+          (PCI_DEVICE_NUMBER_PCH_LPC << 19) |
+          (PCI_FUNCTION_NUMBER_PCH_LPC << 16) |
+          R_ESPI_CFG_PCBC
+        ) }
+      },
+      S_ESPI_CFG_PCBC,
+      N_ESPI_CFG_PCBC_BWPDS
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_TCO
+  }
+};
+
+/**
+  This function will register EspiSmiCallback with mSrcDescEspiBiosWp source decriptor
+  This function make sure there is only one BIOS WP SMI handler is registered.
+  While any ESPI sub BIOS WP SMI type is registered, all the BIOS WP SMI
+  will go to callback function EspiSmiCallback first, and then dispatchs the callbacks
+  recorded in mEspiSmiInstance.
+
+  @retval EFI_SUCCESS Registration succeed
+  @retval others      Registration failed
+**/
+STATIC
+EFI_STATUS
+RegisterBiosWrProtectIfNull (
+  VOID
+  )
+{
+  EFI_STATUS      Status;
+  DATABASE_RECORD *Record;
+
+  if (mEspiSmiInstance.PchSmiEspiHandle[EspiBiosWrProtect] == NULL) {
+    Status = PchSmiRecordInsert (
+               &mSrcDescEspiBiosWp,
+               (PCH_SMI_CALLBACK_FUNCTIONS) EspiSmiCallback,
+               PchTcoSmiLpcBiosWpType,
+               &mEspiSmiInstance.PchSmiEspiHandle[EspiBiosWrProtect]
+               );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "Fail to register BIOS WP SMI handler \n"));
+      return Status;
+    }
+    Record = DATABASE_RECORD_FROM_LINK (mEspiSmiInstance.PchSmiEspiHandle[EspiBiosWrProtect]);
+    Record->ClearSource = PchTcoSmiClearSource;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function will register EspiSmiCallback with mSrcDescSerialIrq source decriptor
+  This function make sure there is only one Serial IRQ SMI handler is registered.
+  While any ESPI sub Serial IRQ SMI type is registered, all the Serial IRQ SMI
+  will go to callback function EspiSmiCallback first, and then dispatchs the callbacks
+  recorded in mEspiSmiInstance.
+
+  @retval EFI_SUCCESS Registration succeed
+  @retval others      Registration failed
+**/
+STATIC
+EFI_STATUS
+RegisterSerialIrqIfNull (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+
+  if (mEspiSmiInstance.PchSmiEspiHandle[EspiSerialIrq] == NULL) {
+    Status = PchSmiRecordInsert (
+               &mSrcDescSerialIrq,
+               (PCH_SMI_CALLBACK_FUNCTIONS) EspiSmiCallback,
+               PchSmiSerialIrqType,
+               &mEspiSmiInstance.PchSmiEspiHandle[EspiSerialIrq]
+               );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "Fail to register Serial IRQ SMI handler \n"));
+      return Status;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Installs and initialize this protocol
+
+  @param[in]  ImageHandle   Not used
+
+  @retval     EFI_SUCCESS   Installation succeed
+  @retval     others        Installation failed
+**/
+EFI_STATUS
+EFIAPI
+InstallEspiSmi (
+  IN EFI_HANDLE           ImageHandle
+  )
+{
+  EFI_STATUS    Status;
+  ESPI_SMI_TYPE EspiSmiType;
+
+  DEBUG ((DEBUG_INFO, "[InstallEspiSmi] Enter\n"));
+
+  //
+  // InitializeListHead for mEspiSmiInstance.CallBackDataBase[EspiTopLevelTypeMax]
+  //
+  for (EspiSmiType = 0; EspiSmiType < EspiSmiTypeMax; ++EspiSmiType) {
+    InitializeListHead (&mEspiSmiInstance.CallbackDataBase[EspiSmiType]);
+  }
+
+  //
+  // Install EfiEspiSmiDispatchProtocol
+  //
+  Status = gSmst->SmmInstallProtocolInterface (
+                    &mEspiSmiInstance.Handle,
+                    &gPchEspiSmiDispatchProtocolGuid,
+                    EFI_NATIVE_INTERFACE,
+                    &mEspiSmiInstance.PchEspiSmiDispatchProtocol
+                    );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed to install eSPI SMI Dispatch Protocol\n"));
+    ASSERT (FALSE);
+    return Status;
+  }
+
+  // Register eSPI SMM callback to enable Fatal Error handling by default handler
+  Status = RegisterSerialIrqIfNull ();
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  // Enable LnkType1Err SMI generation for default handler
+  EspiSmiClearStatus (LnkType1Err);
+  EspiSmiEnableSource (LnkType1Err);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  eSPI SMI Dispatch Protocol instance to register a BIOS Write Protect event
+
+  @param[in]  This              Not used
+  @param[in]  DispatchFunction  The callback to execute
+  @param[out] DispatchHandle    The handle for this callback registration
+
+  @retval     EFI_SUCCESS       Registration succeed
+  @retval     EFI_ACCESS_DENIED Return access denied if the SmmReadyToLock event has been triggered
+  @retval     others            Registration failed
+**/
+EFI_STATUS
+EFIAPI
+BiosWrProtectRegister (
+  IN  PCH_ESPI_SMI_DISPATCH_PROTOCOL  *This,
+  IN  PCH_ESPI_SMI_DISPATCH_CALLBACK  DispatchFunction,
+  OUT EFI_HANDLE                      *DispatchHandle
+  )
+{
+  EFI_STATUS Status;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = RegisterBiosWrProtectIfNull ();
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // Insert a record
+  //
+  Status = InsertEspiRecord (DispatchFunction, BiosWrProtect, DispatchHandle);
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileRegisterHandler (&gPchEspiSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  return Status;
+}
+
+/**
+  eSPI SMI Dispatch Protocol instance to register a BIOS Write Report event
+
+  @param[in]  This              Not used
+  @param[in]  DispatchFunction  The callback to execute
+  @param[out] DispatchHandle    The handle for this callback registration
+
+  @retval     EFI_SUCCESS       Registration succeed
+  @retval     EFI_ACCESS_DENIED Return access denied if the SmmReadyToLock event has been triggered
+  @retval     others            Registration failed
+**/
+EFI_STATUS
+EFIAPI
+BiosWrReportRegister (
+  IN  PCH_ESPI_SMI_DISPATCH_PROTOCOL  *This,
+  IN  PCH_ESPI_SMI_DISPATCH_CALLBACK  DispatchFunction,
+  OUT EFI_HANDLE                      *DispatchHandle
+  )
+{
+  EFI_STATUS Status;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = RegisterSerialIrqIfNull ();
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // Insert a record
+  //
+  Status = InsertEspiRecord (DispatchFunction, BiosWrReport, DispatchHandle);
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileRegisterHandler (&gPchEspiSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  return Status;
+}
+
+/**
+  eSPI SMI Dispatch Protocol instance to register a Peripheral Channel Non Fatal Error event
+
+  @param[in]  This              Not used
+  @param[in]  DispatchFunction  The callback to execute
+  @param[out] DispatchHandle    The handle for this callback registration
+
+  @retval     EFI_SUCCESS       Registration succeed
+  @retval     EFI_ACCESS_DENIED Return access denied if the SmmReadyToLock event has been triggered
+  @retval     others            Registration failed
+**/
+EFI_STATUS
+EFIAPI
+PcNonFatalErrRegister (
+  IN  PCH_ESPI_SMI_DISPATCH_PROTOCOL  *This,
+  IN  PCH_ESPI_SMI_DISPATCH_CALLBACK  DispatchFunction,
+  OUT EFI_HANDLE                      *DispatchHandle
+  )
+{
+  EFI_STATUS Status;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = RegisterSerialIrqIfNull ();
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // Insert a record
+  //
+  Status = InsertEspiRecord (DispatchFunction, PcNonFatalErr, DispatchHandle);
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileRegisterHandler (&gPchEspiSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  return Status;
+}
+
+/**
+  eSPI SMI Dispatch Protocol instance to register a Peripheral Channel Fatal Error event
+
+  @param[in]  This              Not used
+  @param[in]  DispatchFunction  The callback to execute
+  @param[out] DispatchHandle    The handle for this callback registration
+
+  @retval     EFI_SUCCESS       Registration succeed
+  @retval     EFI_ACCESS_DENIED Return access denied if the SmmReadyToLock event has been triggered
+  @retval     others            Registration failed
+**/
+EFI_STATUS
+EFIAPI
+PcFatalErrRegister (
+  IN  PCH_ESPI_SMI_DISPATCH_PROTOCOL  *This,
+  IN  PCH_ESPI_SMI_DISPATCH_CALLBACK  DispatchFunction,
+  OUT EFI_HANDLE                      *DispatchHandle
+  )
+{
+  EFI_STATUS Status;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = RegisterSerialIrqIfNull ();
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // Insert a record
+  //
+  Status = InsertEspiRecord (DispatchFunction, PcFatalErr, DispatchHandle);
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileRegisterHandler (&gPchEspiSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  return Status;
+}
+
+/**
+  eSPI SMI Dispatch Protocol instance to register a Virtual Wire Non Fatal Error event
+
+  @param[in]  This              Not used
+  @param[in]  DispatchFunction  The callback to execute
+  @param[out] DispatchHandle    The handle for this callback registration
+
+  @retval     EFI_SUCCESS       Registration succeed
+  @retval     EFI_ACCESS_DENIED Return access denied if the SmmReadyToLock event has been triggered
+  @retval     others            Registration failed
+**/
+EFI_STATUS
+EFIAPI
+VwNonFatalErrRegister (
+  IN  PCH_ESPI_SMI_DISPATCH_PROTOCOL  *This,
+  IN  PCH_ESPI_SMI_DISPATCH_CALLBACK  DispatchFunction,
+  OUT EFI_HANDLE                      *DispatchHandle
+  )
+{
+  EFI_STATUS  Status;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = RegisterSerialIrqIfNull ();
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // Insert a record
+  //
+  Status = InsertEspiRecord (DispatchFunction, VwNonFatalErr, DispatchHandle);
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileRegisterHandler (&gPchEspiSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  return Status;
+}
+
+/**
+  eSPI SMI Dispatch Protocol instance to register a Virtual Wire Fatal Error event
+
+  @param[in]  This              Not used
+  @param[in]  DispatchFunction  The callback to execute
+  @param[out] DispatchHandle    The handle for this callback registration
+
+  @retval     EFI_SUCCESS       Registration succeed
+  @retval     EFI_ACCESS_DENIED Return access denied if the SmmReadyToLock event has been triggered
+  @retval     others            Registration failed
+**/
+EFI_STATUS
+EFIAPI
+VwFatalErrRegister (
+  IN  PCH_ESPI_SMI_DISPATCH_PROTOCOL  *This,
+  IN  PCH_ESPI_SMI_DISPATCH_CALLBACK  DispatchFunction,
+  OUT EFI_HANDLE                      *DispatchHandle
+  )
+{
+  EFI_STATUS  Status;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = RegisterSerialIrqIfNull ();
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // Insert a record
+  //
+  Status = InsertEspiRecord (DispatchFunction, VwFatalErr, DispatchHandle);
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileRegisterHandler (&gPchEspiSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  return Status;
+}
+
+/**
+  eSPI SMI Dispatch Protocol instance to register a Flash Channel Non Fatal Error event
+
+  @param[in]  This              Not used
+  @param[in]  DispatchFunction  The callback to execute
+  @param[out] DispatchHandle    The handle for this callback registration
+
+  @retval     EFI_SUCCESS       Registration succeed
+  @retval     EFI_ACCESS_DENIED Return access denied if the SmmReadyToLock event has been triggered
+  @retval     others            Registration failed
+**/
+EFI_STATUS
+EFIAPI
+FlashNonFatalErrRegister (
+  IN  PCH_ESPI_SMI_DISPATCH_PROTOCOL  *This,
+  IN  PCH_ESPI_SMI_DISPATCH_CALLBACK  DispatchFunction,
+  OUT EFI_HANDLE                      *DispatchHandle
+  )
+{
+  EFI_STATUS Status;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = RegisterSerialIrqIfNull ();
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // Insert a record
+  //
+  Status = InsertEspiRecord (DispatchFunction, FlashNonFatalErr, DispatchHandle);
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileRegisterHandler (&gPchEspiSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  return Status;
+}
+
+/**
+  eSPI SMI Dispatch Protocol instance to register a Flash Channel Fatal Error event
+
+  @param[in]  This              Not used
+  @param[in]  DispatchFunction  The callback to execute
+  @param[out] DispatchHandle    The handle for this callback registration
+
+  @retval     EFI_SUCCESS       Registration succeed
+  @retval     EFI_ACCESS_DENIED Return access denied if the SmmReadyToLock event has been triggered
+  @retval     others            Registration failed
+**/
+EFI_STATUS
+EFIAPI
+FlashFatalErrRegister (
+  IN  PCH_ESPI_SMI_DISPATCH_PROTOCOL  *This,
+  IN  PCH_ESPI_SMI_DISPATCH_CALLBACK  DispatchFunction,
+  OUT EFI_HANDLE                      *DispatchHandle
+  )
+{
+  EFI_STATUS Status;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = RegisterSerialIrqIfNull ();
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // Insert a record
+  //
+  Status = InsertEspiRecord (DispatchFunction, FlashFatalErr, DispatchHandle);
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileRegisterHandler (&gPchEspiSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  return Status;
+}
+
+/**
+  eSPI SMI Dispatch Protocol instance to register a Link Error event
+
+  @param[in]  This              Not used
+  @param[in]  DispatchFunction  The callback to execute
+  @param[out] DispatchHandle    The handle for this callback registration
+
+  @retval     EFI_SUCCESS       Registration succeed
+  @retval     EFI_ACCESS_DENIED Return access denied if the SmmReadyToLock event has been triggered
+  @retval     others            Registration failed
+**/
+EFI_STATUS
+EFIAPI
+LnkType1ErrRegister (
+  IN  PCH_ESPI_SMI_DISPATCH_PROTOCOL  *This,
+  IN  PCH_ESPI_SMI_DISPATCH_CALLBACK  DispatchFunction,
+  OUT EFI_HANDLE                      *DispatchHandle
+  )
+{
+  EFI_STATUS Status;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = RegisterSerialIrqIfNull ();
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // Insert a record
+  //
+  Status = InsertEspiRecord (DispatchFunction, LnkType1Err, DispatchHandle);
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileRegisterHandler (&gPchEspiSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+  return Status;
+}
+
+//
+// EspiSlave srcdesc
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mSrcDescEspiSlave = {
+  PCH_SMM_NO_FLAGS,
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_EN}
+      },
+      S_ACPI_IO_SMI_EN,
+      N_ACPI_IO_SMI_EN_ESPI
+    },
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_STS}
+      },
+      S_ACPI_IO_SMI_STS,
+      N_ACPI_IO_SMI_STS_ESPI
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_ESPI
+  }
+};
+
+/**
+  eSPI SMI Dispatch Protocol instance to register a eSPI slave SMI
+  This routine will also lock down ESPI_SMI_LOCK bit after registration and prevent
+  this handler from unregistration.
+  On platform that supports more than 1 device through another chip select (SPT-H),
+  the SMI handler itself needs to inspect both the eSPI devices' interrupt status registers
+  (implementation specific for each Slave) in order to identify and service the cause.
+  After servicing it, it has to clear the Slaves' internal SMI# status registers
+
+  @param[in]  This                      Not used
+  @param[in]  DispatchFunction          The callback to execute
+  @param[out] DispatchHandle            The handle for this callback registration
+
+  @retval     EFI_SUCCESS               Registration succeed
+  @retval     EFI_ACCESS_DENIED         Return access denied if the SmmReadyToLock event has been triggered
+  @retval     EFI_ACCESS_DENIED         The ESPI_SMI_LOCK is set and register is blocked.
+  @retval     others                    Registration failed
+**/
+EFI_STATUS
+EFIAPI
+EspiSlaveSmiRegister (
+  IN  PCH_ESPI_SMI_DISPATCH_PROTOCOL    *This,
+  IN  PCH_ESPI_SMI_DISPATCH_CALLBACK    DispatchFunction,
+  OUT EFI_HANDLE                        *DispatchHandle
+  )
+{
+  EFI_STATUS                            Status;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  //
+  // If ESPI_SMI_LOCK is set, the register is blocked.
+  //
+  if (PmcIsEspiSmiLockSet ()) {
+    return EFI_ACCESS_DENIED;
+  }
+
+  //
+  // @note: This service doesn't utilize the data base of mEspiSmiInstance.
+  //        While SMI is triggered it directly goes to the registing DispatchFunction
+  //        instead of EspiSmiCallback.
+  //
+  Status = PchSmiRecordInsert (
+             &mSrcDescEspiSlave,
+             (PCH_SMI_CALLBACK_FUNCTIONS) DispatchFunction,
+             PchEspiSmiEspiSlaveType,
+             DispatchHandle
+             );
+  PchSmmClearSource (&mSrcDescEspiSlave);
+  PchSmmEnableSource (&mSrcDescEspiSlave);
+
+  //
+  // Lock down the ESPI_SMI_LOCK after ESPI SMI is enabled.
+  //
+  PmcLockEspiSmiWithS3BootScript ();
+  //
+  // Keep the DispatchHandle which will be used for unregister function.
+  //
+  mEspiSmiInstance.PchSmiEspiHandle[EspiPmc] = *DispatchHandle;
+
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileRegisterHandler (&gPchEspiSmiDispatchProtocolGuid, (EFI_SMM_HANDLER_ENTRY_POINT2)DispatchFunction, (UINTN)RETURN_ADDRESS (0), NULL, 0);
+  }
+
+  return Status;
+}
+
+/**
+  eSPI SMI Dispatch Protocol instance to unregister a callback based on handle
+
+  @param[in]  This                    Not used
+  @param[in]  DispatchHandle          Handle acquired during registration
+
+  @retval     EFI_SUCCESS             Unregister successful
+  @retval     EFI_INVALID_PARAMETER   DispatchHandle is null
+  @retval     EFI_INVALID_PARAMETER   DispatchHandle's forward link has bad pointer
+  @retval     EFI_INVALID_PARAMETER   DispatchHandle does not exist in database
+  @retval     EFI_ACCESS_DENIED       Unregistration is done after end of DXE
+  @retval     EFI_ACCESS_DENIED       DispatchHandle is not allowed to unregistered
+**/
+EFI_STATUS
+EFIAPI
+EspiSmiUnRegister (
+  IN  PCH_ESPI_SMI_DISPATCH_PROTOCOL  *This,
+  IN  EFI_HANDLE                      DispatchHandle
+  )
+{
+  EFI_STATUS          Status;
+  ESPI_TOP_LEVEL_TYPE EspiTopLevelType;
+  ESPI_SMI_TYPE       EspiSmiType;
+  BOOLEAN             SafeToDisable;
+  LIST_ENTRY          *LinkInDb;
+  ESPI_SMI_RECORD     *RecordPointer;
+  DATABASE_RECORD    *RecordToDelete;
+
+  if (DispatchHandle == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "UnRegister is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  if (((LIST_ENTRY *) DispatchHandle)->ForwardLink == (LIST_ENTRY *) EFI_BAD_POINTER) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // For DispatchHandle belongs to Espi Slave SMI, refuses the request of unregistration.
+  //
+  if (mEspiSmiInstance.PchSmiEspiHandle[EspiPmc] == DispatchHandle) {
+    DEBUG ((DEBUG_ERROR, "UnRegister is not allowed for ESPI Slave SMI handle! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  //
+  // Iterate through all the database to find the record
+  //
+  for (EspiSmiType = 0; EspiSmiType < EspiSmiTypeMax; ++EspiSmiType) {
+    LinkInDb = GetFirstNode (&mEspiSmiInstance.CallbackDataBase[EspiSmiType]);
+
+    while (!IsNull (&mEspiSmiInstance.CallbackDataBase[EspiSmiType], LinkInDb)) {
+      if (LinkInDb != (LIST_ENTRY *) DispatchHandle) {
+        LinkInDb = GetNextNode (&mEspiSmiInstance.CallbackDataBase[EspiSmiType], LinkInDb);
+
+      } else {
+        //
+        // Found the source to be from this list
+        //
+        RemoveEntryList (LinkInDb);
+        RecordPointer = (ESPI_RECORD_FROM_LINK (LinkInDb));
+
+        if (mEspiSmiInstance.EspiSmiEventCounter[EspiSmiType] != 0) {
+          if (--mEspiSmiInstance.EspiSmiEventCounter[EspiSmiType] == 0) {
+            EspiSmiDisableSource (EspiSmiType);
+          }
+        }
+
+        Status = gSmst->SmmFreePool (RecordPointer);
+        if (EFI_ERROR (Status)) {
+          ASSERT (FALSE);
+        }
+
+        goto EspiSmiUnRegisterEnd;
+      }
+    }
+  }
+  //
+  // If the code reach here, the handle passed in cannot be found
+  //
+  DEBUG ((DEBUG_ERROR, "eSPI SMI handle is not in record database \n"));
+  ASSERT (FALSE);
+  return EFI_INVALID_PARAMETER;
+
+EspiSmiUnRegisterEnd:
+
+  //
+  // Unregister and clear the handle from PchSmiDispatch
+  //
+  for (EspiTopLevelType = 0; EspiTopLevelType < EspiTopLevelTypeMax; ++EspiTopLevelType) {
+    SafeToDisable = TRUE;
+    //
+    // Checks all the child events that belongs to a top level status in PMC
+    //
+    for (EspiSmiType = mEspiSmiInstance.Barrier[EspiTopLevelType].Start; EspiSmiType <= mEspiSmiInstance.Barrier[EspiTopLevelType].End; ++EspiSmiType) {
+      if (mEspiSmiInstance.EspiSmiEventCounter[EspiSmiType] != 0) {
+        SafeToDisable = FALSE;
+      }
+    }
+    //
+    // Finally, disable the top level event in PMC
+    //
+    if (SafeToDisable) {
+      if (mEspiSmiInstance.PchSmiEspiHandle[EspiTopLevelType] != NULL) {
+        Status = PchSmmCoreUnRegister (NULL, mEspiSmiInstance.PchSmiEspiHandle[EspiTopLevelType]);
+        ASSERT_EFI_ERROR (Status);
+        mEspiSmiInstance.PchSmiEspiHandle[EspiTopLevelType] = NULL;
+      }
+    }
+  }
+  RecordToDelete = DATABASE_RECORD_FROM_LINK (DispatchHandle);
+  if (!EFI_ERROR (Status)) {
+    SmiHandlerProfileUnregisterHandler (&gPchEspiSmiDispatchProtocolGuid, RecordToDelete->Callback, NULL, 0);
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  Returns AND maks for clearing eSPI channel registers errors statuses
+  In addition to common status bit we add channel specific erro bits to avoid clearing them
+
+  @param[in]  ChannelNumber           Channel number (0 for PC, 1 for VW, 2 for OOB, 3 for FA)
+
+  @retval     UINT32                  AND mask with all the status bit masked to not clear them by mistake
+**/
+UINT32
+GetEspiChannelStatusClearMask (
+  UINT8       ChannelNumber
+  )
+{
+  UINT32    Data32;
+
+  // Common error status bits for all channel registers
+  Data32 = B_ESPI_PCR_XERR_XNFES | B_ESPI_PCR_XERR_XFES;
+
+  // Check channels for channel specific status bits
+  switch(ChannelNumber) {
+    case 0:   // Peripheral Channel specific status bits
+      Data32 |= B_ESPI_PCR_PCERR_PCURD;
+      break;
+    case 3:   // Flash Access Channel specific status bits
+      Data32 |= B_ESPI_PCR_FCERR_SAFBLK;
+      break;
+  }
+
+  // Return the expected AND mask
+  return (UINT32)~(Data32);
+}
+
+/**
+  Checks if channel error register data has Fatal Error bit set
+  If yes then reset the channel on slave
+
+  @param[in]  ChannelBaseAddress      Base address
+  @param[in]  ChannelNumber           Channel number (0 for PC, 1 for VW, 2 for OOB, 3 for FA)
+  @param[in]  SlaveId                 Slave ID of which channel is to be reset
+**/
+VOID
+CheckSlaveChannelErrorAndReset (
+  UINT16      ChannelBaseAddress,
+  UINT8       ChannelNumber,
+  UINT8       SlaveId
+  )
+{
+  UINT32      Data32;
+  UINT16      ChannelAddress;
+  EFI_STATUS  Status;
+
+  if (ChannelNumber == 2) {
+    DEBUG ((DEBUG_INFO, "Channel %d is not supported by this function due to lack of error register\n", ChannelNumber));
+    return;
+  }
+
+  if (!IsEspiSlaveChannelSupported (SlaveId, ChannelNumber)) {
+    DEBUG ((DEBUG_WARN, "Channel %d is not supported by slave device\n", ChannelNumber));
+    return;
+  }
+
+  // Calculate channel address based on slave id
+  ChannelAddress = (UINT16) (ChannelBaseAddress + (SlaveId * S_ESPI_PCR_XERR));
+
+  // Reading channel error register data
+  Data32 = PchPcrRead32 (PID_ESPISPI, ChannelAddress);
+
+  DEBUG ((DEBUG_INFO, "eSPI channel error register (0x%4X) has value 0x%8X\n", ChannelAddress, Data32));
+
+  // Check Fatal Error status bit in channel error register data
+  if ((Data32 & B_ESPI_PCR_XERR_XFES) != 0) {
+    Status = PchEspiSlaveChannelReset (SlaveId, ChannelNumber);
+
+    if (EFI_ERROR (Status)) {
+      switch (Status) {
+        case EFI_UNSUPPORTED:
+          DEBUG ((DEBUG_ERROR, "Slave doesn't support channel %d\n", ChannelNumber));
+          break;
+        case EFI_TIMEOUT:
+          DEBUG ((DEBUG_ERROR, "Timeout occured during channel %d reset on slave %d\n", ChannelNumber, SlaveId));
+          break;
+        default:
+          DEBUG ((DEBUG_ERROR, "Error occured during channel %d reset\n", ChannelNumber));
+          break;
+      }
+    } else {
+      DEBUG ((DEBUG_INFO, "eSPI Slave %d channel %d reset ended successfully\n", SlaveId, ChannelNumber));
+      // If channel reset was successfull clear the fatal error flag by writing one
+      // we should be aware not to clear other status bits by mistake and mask them
+      PchPcrAndThenOr32 (
+        PID_ESPISPI,
+        ChannelAddress,
+        GetEspiChannelStatusClearMask (ChannelNumber),
+        B_ESPI_PCR_XERR_XFES
+        );
+    }
+  }
+}
+
+/**
+  eSPI SMI handler for Fatal Error recovery flow
+**/
+VOID
+EspiDefaultFatalErrorHandler (
+  VOID
+  )
+{
+  UINT32      Data32;
+  UINT8       SlaveId;
+  UINT8       MaxSlavesCount;
+
+  DEBUG ((DEBUG_INFO, "[EspiRecoverFromFatalError] Enter\n"));
+
+  MaxSlavesCount = IsEspiSecondSlaveSupported () ? 2 : 1;
+
+  DEBUG ((DEBUG_INFO, "[EspiRecoverFromFatalError] MaxSlavesCount %d\n", MaxSlavesCount));
+
+  for (SlaveId = 0; SlaveId < MaxSlavesCount; ++SlaveId) {
+    //
+    // Check if slave has SLCRR bit set. If it does it means it needs recovery.
+    //
+    Data32 = PchPcrRead32 (PID_ESPISPI, (UINT16) (R_ESPI_PCR_LNKERR_SLV0 + (SlaveId * S_ESPI_PCR_XERR)));
+
+    DEBUG ((DEBUG_INFO, "[EspiRecoverFromFatalError] Slave %d LNKERR reg 0x%8X\n", SlaveId, Data32));
+    //
+    // If SLCRR[31] bit is set we need to recover that slave
+    //
+    if ((Data32 & B_ESPI_PCR_LNKERR_SLV0_SLCRR) != 0) {
+      // 1. Perform in-band reset
+      PchEspiSlaveInBandReset (SlaveId);
+
+      // 2. Channels reset
+      CheckSlaveChannelErrorAndReset (R_ESPI_PCR_PCERR_SLV0, 0, SlaveId); // Peripheral channel reset
+      CheckSlaveChannelErrorAndReset (R_ESPI_PCR_VWERR_SLV0, 1, SlaveId); // Virtual Wire channel reset
+
+      // Flash Access channel is not supported for CS1#
+      if (SlaveId == 0) {
+        CheckSlaveChannelErrorAndReset (R_ESPI_PCR_PCERR_SLV0, 3, SlaveId); // Flash Access channel reset
+      }
+
+      // Clear SLCRR bit of slave after all channels recovery was done
+      PchPcrAndThenOr32 (
+        PID_ESPISPI,
+        (UINT16) (R_ESPI_PCR_LNKERR_SLV0 + (SlaveId * S_ESPI_PCR_XERR)),
+        (UINT32)~(B_ESPI_PCR_LNKERR_SLV0_LFET1S),
+        (UINT32) (B_ESPI_PCR_LNKERR_SLV0_SLCRR)
+        );
+    }
+  }
+
+  DEBUG ((DEBUG_INFO, "[EspiRecoverFromFatalError] Exit\n"));
+}
+
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.h
new file mode 100644
index 0000000000..4903464fae
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmEspi.h
@@ -0,0 +1,341 @@
+/** @file
+  eSPI SMI Dispatch header
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_SMM_ESPI_H_
+#define _PCH_SMM_ESPI_H_
+
+#include "PchSmmHelpers.h"
+
+#define ESPI_SMI_INSTANCE_SIGNATURE       SIGNATURE_32 ('E', 'S', 'P', 'I')
+#define ESPI_SMI_RECORD_SIGNATURE         SIGNATURE_32 ('E', 'S', 'R', 'C')
+
+#define ESPI_INSTANCE_FROM_THIS(_this)      CR (_this, ESPI_SMI_INSTANCE, EfiEspiSmiDispatchProtocol, ESPI_SMI_INSTANCE_SIGNATURE)
+#define ESPI_RECORD_FROM_LINK(_link)        CR (_link, ESPI_SMI_RECORD, Link, ESPI_SMI_RECORD_SIGNATURE)
+
+typedef enum {
+  EspiBiosWrProtect,    ///< BIOS Write Protect
+  EspiSerialIrq,        ///< eSPI Master Asserted SMI
+  EspiPmc,              ///< eSPI PMC SMI
+  EspiTopLevelTypeMax
+} ESPI_TOP_LEVEL_TYPE;
+
+typedef enum {
+  BiosWrProtect,        ///< BIOS Write Protect
+  BiosWrReport,         ///< Peripheral Channel BIOS Write Protect
+  PcNonFatalErr,        ///< Peripheral Channel Non Fatal Error
+  PcFatalErr,           ///< Peripheral Channel Fatal Error
+  VwNonFatalErr,        ///< Virtual Wire Non Fatal Error
+  VwFatalErr,           ///< Virtual Wire Fatal Error
+  FlashNonFatalErr,     ///< Flash Channel Non Fatal Error
+  FlashFatalErr,        ///< Flash Channel Fatal Error
+  LnkType1Err,          ///< Link Error
+  EspiSlaveSmi,         ///< Espi Slave SMI
+  EspiSmiTypeMax
+} ESPI_SMI_TYPE;
+
+///
+/// This is used to classify ESPI_SMI_TYPE to ESPI_TOP_LEVEL_TYPE.
+/// Used during dispatching and unregistering
+///
+typedef struct {
+  ESPI_SMI_TYPE Start;
+  ESPI_SMI_TYPE End;
+} ESPI_SMI_TYPE_BARRIER;
+
+typedef struct _ESPI_SMI_INSTANCE {
+  ///
+  /// Signature associated with this instance
+  ///
+  UINT32                          Signature;
+  ///
+  /// EFI_HANDLE acquired when installing PchEspiSmiDispatchProtocol
+  ///
+  EFI_HANDLE                      Handle;
+  ///
+  /// The protocol to register or unregister eSPI SMI callbacks
+  ///
+  PCH_ESPI_SMI_DISPATCH_PROTOCOL  PchEspiSmiDispatchProtocol;
+  ///
+  /// The handle acquired when registering eSPI SMI callback to PchSmiDispatch
+  ///
+  EFI_HANDLE                      PchSmiEspiHandle[EspiTopLevelTypeMax];
+  ///
+  /// The linked list for record database.
+  ///
+  LIST_ENTRY                      CallbackDataBase[EspiSmiTypeMax];
+  ///
+  /// This is an internal counter to track the number of eSPI master events have been registered.
+  /// When unregistering, we can disable the SMI if the counter is zero
+  ///
+  UINTN                           EspiSmiEventCounter[EspiSmiTypeMax];
+  ///
+  /// Instance of barrier
+  ///
+  CONST ESPI_SMI_TYPE_BARRIER     Barrier[EspiTopLevelTypeMax];
+} ESPI_SMI_INSTANCE;
+
+typedef struct _ESPI_DESCRIPTOR {
+  PCH_SMM_ADDRESS   Address;
+  UINT32            SourceIsActiveAndMask;
+  UINT32            SourceIsActiveValue;
+  UINT32            ClearStatusAndMask;
+  UINT32            ClearStatusOrMask;
+} ESPI_DESCRIPTOR;
+
+///
+/// A simple record to store the callbacks associated with an eSPI SMI source
+///
+typedef struct _ESPI_SMI_RECORD {
+  UINT32                          Signature;
+  LIST_ENTRY                      Link;
+  PCH_ESPI_SMI_DISPATCH_CALLBACK  Callback;
+} ESPI_SMI_RECORD;
+
+/**
+  Installs and initialize this protocol
+
+  @param[in]  ImageHandle   Not used
+
+  @retval     EFI_SUCCESS   Installation succeed
+  @retval     others        Installation failed
+**/
+EFI_STATUS
+EFIAPI
+InstallEspiSmi (
+  IN EFI_HANDLE           ImageHandle
+  );
+
+/**
+  eSPI SMI Dispatch Protocol instance to register a BIOS Write Protect event
+
+  @param[in]  This              Not used
+  @param[in]  DispatchFunction  The callback to execute
+  @param[out] DispatchHandle    The handle for this callback registration
+
+  @retval     EFI_SUCCESS       Registration succeed
+  @retval     EFI_ACCESS_DENIED Return access denied if the SmmReadyToLock event has been triggered
+  @retval     others            Registration failed
+**/
+EFI_STATUS
+EFIAPI
+BiosWrProtectRegister (
+  IN  PCH_ESPI_SMI_DISPATCH_PROTOCOL  *This,
+  IN  PCH_ESPI_SMI_DISPATCH_CALLBACK  DispatchFunction,
+  OUT EFI_HANDLE                      *DispatchHandle
+  );
+
+/**
+  eSPI SMI Dispatch Protocol instance to register a BIOS Write Report event
+
+  @param[in]  This              Not used
+  @param[in]  DispatchFunction  The callback to execute
+  @param[out] DispatchHandle    The handle for this callback registration
+
+  @retval     EFI_SUCCESS       Registration succeed
+  @retval     EFI_ACCESS_DENIED Return access denied if the SmmReadyToLock event has been triggered
+  @retval     others            Registration failed
+**/
+EFI_STATUS
+EFIAPI
+BiosWrReportRegister (
+  IN  PCH_ESPI_SMI_DISPATCH_PROTOCOL  *This,
+  IN  PCH_ESPI_SMI_DISPATCH_CALLBACK  DispatchFunction,
+  OUT EFI_HANDLE                      *DispatchHandle
+  );
+
+/**
+  eSPI SMI Dispatch Protocol instance to register a Peripheral Channel Non Fatal Error event
+
+  @param[in]  This              Not used
+  @param[in]  DispatchFunction  The callback to execute
+  @param[out] DispatchHandle    The handle for this callback registration
+
+  @retval     EFI_SUCCESS       Registration succeed
+  @retval     EFI_ACCESS_DENIED Return access denied if the SmmReadyToLock event has been triggered
+  @retval     others            Registration failed
+**/
+EFI_STATUS
+EFIAPI
+PcNonFatalErrRegister (
+  IN  PCH_ESPI_SMI_DISPATCH_PROTOCOL  *This,
+  IN  PCH_ESPI_SMI_DISPATCH_CALLBACK  DispatchFunction,
+  OUT EFI_HANDLE                      *DispatchHandle
+  );
+
+/**
+  eSPI SMI Dispatch Protocol instance to register a Peripheral Channel Fatal Error event
+
+  @param[in]  This              Not used
+  @param[in]  DispatchFunction  The callback to execute
+  @param[out] DispatchHandle    The handle for this callback registration
+
+  @retval     EFI_SUCCESS       Registration succeed
+  @retval     EFI_ACCESS_DENIED Return access denied if the SmmReadyToLock event has been triggered
+  @retval     others            Registration failed
+**/
+EFI_STATUS
+EFIAPI
+PcFatalErrRegister (
+  IN  PCH_ESPI_SMI_DISPATCH_PROTOCOL  *This,
+  IN  PCH_ESPI_SMI_DISPATCH_CALLBACK  DispatchFunction,
+  OUT EFI_HANDLE                      *DispatchHandle
+  );
+
+/**
+  eSPI SMI Dispatch Protocol instance to register a Virtual Wire Non Fatal Error event
+
+  @param[in]  This              Not used
+  @param[in]  DispatchFunction  The callback to execute
+  @param[out] DispatchHandle    The handle for this callback registration
+
+  @retval     EFI_SUCCESS       Registration succeed
+  @retval     EFI_ACCESS_DENIED Return access denied if the SmmReadyToLock event has been triggered
+  @retval     others            Registration failed
+**/
+EFI_STATUS
+EFIAPI
+VwNonFatalErrRegister (
+  IN  PCH_ESPI_SMI_DISPATCH_PROTOCOL  *This,
+  IN  PCH_ESPI_SMI_DISPATCH_CALLBACK  DispatchFunction,
+  OUT EFI_HANDLE                      *DispatchHandle
+  );
+
+/**
+  eSPI SMI Dispatch Protocol instance to register a Virtual Wire Fatal Error event
+
+  @param[in]  This              Not used
+  @param[in]  DispatchFunction  The callback to execute
+  @param[out] DispatchHandle    The handle for this callback registration
+
+  @retval     EFI_SUCCESS       Registration succeed
+  @retval     EFI_ACCESS_DENIED Return access denied if the SmmReadyToLock event has been triggered
+  @retval     others            Registration failed
+**/
+EFI_STATUS
+EFIAPI
+VwFatalErrRegister (
+  IN  PCH_ESPI_SMI_DISPATCH_PROTOCOL  *This,
+  IN  PCH_ESPI_SMI_DISPATCH_CALLBACK  DispatchFunction,
+  OUT EFI_HANDLE                      *DispatchHandle
+  );
+
+/**
+  eSPI SMI Dispatch Protocol instance to register a Flash Channel Non Fatal Error event
+
+  @param[in]  This              Not used
+  @param[in]  DispatchFunction  The callback to execute
+  @param[out] DispatchHandle    The handle for this callback registration
+
+  @retval     EFI_SUCCESS       Registration succeed
+  @retval     EFI_ACCESS_DENIED Return access denied if the SmmReadyToLock event has been triggered
+  @retval     others            Registration failed
+**/
+EFI_STATUS
+EFIAPI
+FlashNonFatalErrRegister (
+  IN  PCH_ESPI_SMI_DISPATCH_PROTOCOL  *This,
+  IN  PCH_ESPI_SMI_DISPATCH_CALLBACK  DispatchFunction,
+  OUT EFI_HANDLE                      *DispatchHandle
+  );
+
+/**
+  eSPI SMI Dispatch Protocol instance to register a Flash Channel Fatal Error event
+
+  @param[in]  This              Not used
+  @param[in]  DispatchFunction  The callback to execute
+  @param[out] DispatchHandle    The handle for this callback registration
+
+  @retval     EFI_SUCCESS       Registration succeed
+  @retval     EFI_ACCESS_DENIED Return access denied if the SmmReadyToLock event has been triggered
+  @retval     others            Registration failed
+**/
+EFI_STATUS
+EFIAPI
+FlashFatalErrRegister (
+  IN  PCH_ESPI_SMI_DISPATCH_PROTOCOL  *This,
+  IN  PCH_ESPI_SMI_DISPATCH_CALLBACK  DispatchFunction,
+  OUT EFI_HANDLE                      *DispatchHandle
+  );
+
+/**
+  eSPI SMI Dispatch Protocol instance to register a Link Error event
+
+  @param[in]  This              Not used
+  @param[in]  DispatchFunction  The callback to execute
+  @param[out] DispatchHandle    The handle for this callback registration
+
+  @retval     EFI_SUCCESS       Registration succeed
+  @retval     EFI_ACCESS_DENIED Return access denied if the SmmReadyToLock event has been triggered
+  @retval     others            Registration failed
+**/
+EFI_STATUS
+EFIAPI
+LnkType1ErrRegister (
+  IN  PCH_ESPI_SMI_DISPATCH_PROTOCOL  *This,
+  IN  PCH_ESPI_SMI_DISPATCH_CALLBACK  DispatchFunction,
+  OUT EFI_HANDLE                      *DispatchHandle
+  );
+
+/**
+  eSPI SMI Dispatch Protocol instance to register a eSPI slave SMI
+  NOTE: The register function is not available when the ESPI_SMI_LOCK bit is set.
+        This runtine will also lock donw ESPI_SMI_LOCK bit after registration and
+        prevent this handler from unregistration.
+  On platform that supports more than 1 device through another chip select (SPT-H),
+  the SMI handler itself needs to inspect both the eSPI devices' interrupt status registers
+  (implementation specific for each Slave) in order to identify and service the cause.
+  After servicing it, it has to clear the Slaves' internal SMI# status registers
+
+  @param[in]  This                      Not used
+  @param[in]  DispatchFunction          The callback to execute
+  @param[out] DispatchHandle            The handle for this callback registration
+
+  @retval     EFI_SUCCESS               Registration succeed
+  @retval     EFI_ACCESS_DENIED         Return access denied if the SmmReadyToLock event has been triggered
+  @retval     EFI_ACCESS_DENIED         The ESPI_SMI_LOCK is set and register is blocked.
+  @retval     others                    Registration failed
+**/
+EFI_STATUS
+EFIAPI
+EspiSlaveSmiRegister (
+  IN  PCH_ESPI_SMI_DISPATCH_PROTOCOL    *This,
+  IN  PCH_ESPI_SMI_DISPATCH_CALLBACK    DispatchFunction,
+  OUT EFI_HANDLE                        *DispatchHandle
+  );
+
+/**
+  eSPI SMI Dispatch Protocol instance to unregister a callback based on handle
+
+  @param[in]  This                    Not used
+  @param[in]  DispatchHandle          Handle acquired during registration
+
+  @retval     EFI_SUCCESS             Unregister successful
+  @retval     EFI_INVALID_PARAMETER   DispatchHandle is null
+  @retval     EFI_INVALID_PARAMETER   DispatchHandle's forward link has bad pointer
+  @retval     EFI_INVALID_PARAMETER   DispatchHandle does not exist in database
+  @retval     EFI_ACCESS_DENIED       Unregistration is done after end of DXE
+  @retval     EFI_ACCESS_DENIED       DispatchHandle is not allowed to unregistered
+**/
+EFI_STATUS
+EFIAPI
+EspiSmiUnRegister (
+  IN  PCH_ESPI_SMI_DISPATCH_PROTOCOL  *This,
+  IN  EFI_HANDLE                      DispatchHandle
+  );
+
+/**
+  eSPI SMI handler for Fatal Error recovery flow
+
+  @param[in]  DispatchHandle          Handle acquired during registration
+**/
+VOID
+EspiDefaultFatalErrorHandler (
+  VOID
+  );
+
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmGpi.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmGpi.c
new file mode 100644
index 0000000000..61f925c860
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmGpi.c
@@ -0,0 +1,263 @@
+/** @file
+  File to contain all the hardware specific stuff for the Smm Gpi dispatch protocol.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "PchSmm.h"
+#include "PchSmmHelpers.h"
+#include <Library/SmiHandlerProfileLib.h>
+#include <Register/GpioRegs.h>
+#include <Register/PmcRegs.h>
+
+//
+// Structure for GPI SMI is a template which needs to have
+// GPI Smi bit offset and Smi Status & Enable registers updated (accordingly
+// to choosen group and pad number) after adding it to SMM Callback database
+//
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mPchGpiSourceDescTemplate = {
+  PCH_SMM_NO_FLAGS,
+  {
+    NULL_BIT_DESC_INITIALIZER,
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        GPIO_ADDR_TYPE, {0x0}
+      },
+      S_GPIO_PCR_GP_SMI_STS, 0x0,
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_GPIO_SMI
+  }
+};
+
+/**
+  The register function used to register SMI handler of GPI SMI event.
+
+  @param[in]  This               Pointer to the EFI_SMM_GPI_DISPATCH2_PROTOCOL instance.
+  @param[in]  DispatchFunction   Function to register for handler when the specified GPI causes an SMI.
+  @param[in]  RegisterContext    Pointer to the dispatch function's context.
+                                 The caller fills this context in before calling
+                                 the register function to indicate to the register
+                                 function the GPI(s) for which the dispatch function
+                                 should be invoked.
+  @param[out] DispatchHandle     Handle generated by the dispatcher to track the
+                                 function instance.
+
+  @retval EFI_SUCCESS            The dispatch function has been successfully
+                                 registered and the SMI source has been enabled.
+  @retval EFI_ACCESS_DENIED      Register is not allowed
+  @retval EFI_INVALID_PARAMETER  RegisterContext is invalid. The GPI input value
+                                 is not within valid range.
+  @retval EFI_OUT_OF_RESOURCES   There is not enough memory (system or SMM) to manage this child.
+**/
+EFI_STATUS
+EFIAPI
+PchGpiSmiRegister (
+  IN CONST EFI_SMM_GPI_DISPATCH2_PROTOCOL  *This,
+  IN       EFI_SMM_HANDLER_ENTRY_POINT2    DispatchFunction,
+  IN       EFI_SMM_GPI_REGISTER_CONTEXT    *RegisterContext,
+  OUT      EFI_HANDLE                      *DispatchHandle
+  )
+{
+  EFI_STATUS                  Status;
+  DATABASE_RECORD             Record;
+  GPIO_PAD                    GpioPad;
+  UINT8                       GpiSmiBitOffset;
+  UINT32                      GpiHostSwOwnRegAddress;
+  UINT32                      GpiSmiStsRegAddress;
+  UINT32                      Data32Or;
+  UINT32                      Data32And;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the EndOfDxe event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  Status = GpioGetPadAndSmiRegs (
+             (UINT32) RegisterContext->GpiNum,
+             &GpioPad,
+             &GpiSmiBitOffset,
+             &GpiHostSwOwnRegAddress,
+             &GpiSmiStsRegAddress
+             );
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ZeroMem (&Record, sizeof (DATABASE_RECORD));
+
+  //
+  // Gather information about the registration request
+  //
+  Record.Callback          = DispatchFunction;
+  Record.ChildContext.Gpi  = *RegisterContext;
+  Record.ProtocolType      = GpiType;
+  Record.Signature         = DATABASE_RECORD_SIGNATURE;
+
+  CopyMem (&Record.SrcDesc, &mPchGpiSourceDescTemplate, sizeof (PCH_SMM_SOURCE_DESC) );
+
+  Record.SrcDesc.Sts[0].Reg.Data.raw = GpiSmiStsRegAddress;  // GPI SMI Status register
+  Record.SrcDesc.Sts[0].Bit = GpiSmiBitOffset;               // Bit position for selected pad
+
+  //
+  // Insert GpiSmi handler to PchSmmCore database
+  //
+  *DispatchHandle = NULL;
+
+  Status = SmmCoreInsertRecord (
+             &Record,
+             DispatchHandle
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  SmiHandlerProfileRegisterHandler (
+    &gEfiSmmGpiDispatch2ProtocolGuid,
+    (EFI_SMM_HANDLER_ENTRY_POINT2) DispatchFunction,
+    (UINTN)RETURN_ADDRESS (0),
+    RegisterContext,
+    sizeof(*RegisterContext)
+    );
+
+  //
+  // Enable GPI SMI
+  // HOSTSW_OWN with respect to generating GPI SMI has negative logic:
+  //  - 0 (ACPI mode) - GPIO pad will be capable of generating SMI/NMI/SCI
+  //  - 1 (GPIO mode) - GPIO pad will not generate SMI/NMI/SCI
+  //
+  Data32And  = (UINT32)~(1u << GpiSmiBitOffset);
+  MmioAnd32 (GpiHostSwOwnRegAddress, Data32And);
+
+  //
+  // Add HOSTSW_OWN programming into S3 boot script
+  //
+  Data32Or = 0;
+  S3BootScriptSaveMemReadWrite (S3BootScriptWidthUint32, GpiHostSwOwnRegAddress, &Data32Or, &Data32And);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Unregister a GPI SMI source dispatch function with a parent SMM driver
+
+  @param[in] This                 Pointer to the EFI_SMM_GPI_DISPATCH2_PROTOCOL instance.
+  @param[in] DispatchHandle       Handle of dispatch function to deregister.
+
+  @retval EFI_SUCCESS             The dispatch function has been successfully
+                                  unregistered and the SMI source has been disabled
+                                  if there are no other registered child dispatch
+                                  functions for this SMI source.
+  @retval EFI_INVALID_PARAMETER   Handle is invalid.
+**/
+EFI_STATUS
+EFIAPI
+PchGpiSmiUnRegister (
+  IN CONST EFI_SMM_GPI_DISPATCH2_PROTOCOL  *This,
+  IN       EFI_HANDLE                      DispatchHandle
+  )
+{
+  EFI_STATUS      Status;
+  DATABASE_RECORD *RecordToDelete;
+  DATABASE_RECORD *RecordInDb;
+  LIST_ENTRY      *LinkInDb;
+  GPIO_PAD        GpioPad;
+  UINT8           GpiSmiBitOffset;
+  UINT32          GpiHostSwOwnRegAddress;
+  UINT32          GpiSmiStsRegAddress;
+  UINT32          Data32Or;
+  UINT32          Data32And;
+  BOOLEAN         DisableGpiSmiSource;
+
+
+  if (DispatchHandle == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  RecordToDelete = DATABASE_RECORD_FROM_LINK (DispatchHandle);
+  if ((RecordToDelete->Signature != DATABASE_RECORD_SIGNATURE) ||
+      (RecordToDelete->ProtocolType != GpiType)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "UnRegister is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  DisableGpiSmiSource = TRUE;
+  //
+  // Loop through all sources in record linked list to see if any other GPI SMI
+  // is installed on the same pin. If no then disable GPI SMI capability on this pad
+  //
+  LinkInDb = GetFirstNode (&mPrivateData.CallbackDataBase);
+  while (!IsNull (&mPrivateData.CallbackDataBase, LinkInDb)) {
+    RecordInDb = DATABASE_RECORD_FROM_LINK (LinkInDb);
+    LinkInDb = GetNextNode (&mPrivateData.CallbackDataBase, &RecordInDb->Link);
+    //
+    // If this is the record to delete skip it
+    //
+    if (RecordInDb == RecordToDelete) {
+      continue;
+    }
+    //
+    // Check if record is GPI SMI type
+    //
+    if (RecordInDb->ProtocolType == GpiType) {
+      //
+      // Check if same GPIO pad is the source of this SMI
+      //
+      if (RecordInDb->ChildContext.Gpi.GpiNum == RecordToDelete->ChildContext.Gpi.GpiNum) {
+        DisableGpiSmiSource = FALSE;
+        break;
+      }
+    }
+  }
+
+  if (DisableGpiSmiSource) {
+    GpioGetPadAndSmiRegs (
+      (UINT32) RecordToDelete->ChildContext.Gpi.GpiNum,
+      &GpioPad,
+      &GpiSmiBitOffset,
+      &GpiHostSwOwnRegAddress,
+      &GpiSmiStsRegAddress
+      );
+
+    Data32Or = 1u << GpiSmiBitOffset;
+    Data32And = 0xFFFFFFFF;
+    MmioOr32 (GpiHostSwOwnRegAddress, Data32Or);
+    S3BootScriptSaveMemReadWrite (S3BootScriptWidthUint32, GpiHostSwOwnRegAddress, &Data32Or, &Data32And);
+  }
+
+
+  RemoveEntryList (&RecordToDelete->Link);
+  ZeroMem (RecordToDelete, sizeof (DATABASE_RECORD));
+  Status = gSmst->SmmFreePool (RecordToDelete);
+
+  if (EFI_ERROR (Status)) {
+    ASSERT (FALSE);
+    return Status;
+  }
+  SmiHandlerProfileUnregisterHandler (
+    &gEfiSmmGpiDispatch2ProtocolGuid,
+    RecordToDelete->Callback,
+    &RecordToDelete->ChildContext,
+    RecordToDelete->ContextSize
+    );
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.c
new file mode 100644
index 0000000000..6bbf9ea8e8
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.c
@@ -0,0 +1,332 @@
+/** @file
+  Helper functions for PCH SMM dispatcher.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "PchSmmHelpers.h"
+#include <Register/PmcRegs.h>
+
+///
+/// #define BIT_ZERO 0x00000001
+///
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32  BIT_ZERO = 0x00000001;
+
+///
+/// SUPPORT / HELPER FUNCTIONS (PCH version-independent)
+///
+
+/**
+  Compare 2 SMM source descriptors' enable settings.
+
+  @param[in] Src1                 Pointer to the PCH SMI source description table 1
+  @param[in] Src2                 Pointer to the PCH SMI source description table 2
+
+  @retval TRUE                    The enable settings of the 2 SMM source descriptors are identical.
+  @retval FALSE                   The enable settings of the 2 SMM source descriptors are not identical.
+**/
+BOOLEAN
+CompareEnables (
+  CONST IN PCH_SMM_SOURCE_DESC *Src1,
+  CONST IN PCH_SMM_SOURCE_DESC *Src2
+  )
+{
+  BOOLEAN IsEqual;
+  UINTN   DescIndex;
+
+  IsEqual = TRUE;
+  for (DescIndex = 0; DescIndex < NUM_EN_BITS; DescIndex++) {
+    ///
+    /// It's okay to compare a NULL bit description to a non-NULL bit description.
+    /// They are unequal and these tests will generate the correct result.
+    ///
+    if (Src1->En[DescIndex].Bit != Src2->En[DescIndex].Bit ||
+        Src1->En[DescIndex].Reg.Type != Src2->En[DescIndex].Reg.Type ||
+        Src1->En[DescIndex].Reg.Data.raw != Src2->En[DescIndex].Reg.Data.raw
+        ) {
+      IsEqual = FALSE;
+      break;
+      ///
+      /// out of for loop
+      ///
+    }
+  }
+
+  return IsEqual;
+}
+
+/**
+  Compare a bit descriptor to the enables of source descriptor. Includes null address type.
+
+  @param[in] BitDesc              Pointer to the PCH SMI bit descriptor
+  @param[in] Src                  Pointer to the PCH SMI source description table 2
+
+  @retval TRUE                    The bit desc is equal to any of the enables in source descriptor
+  @retval FALSE                   The bid desc is not equal to all of the enables in source descriptor
+**/
+BOOLEAN
+IsBitEqualToAnySourceEn (
+  CONST IN PCH_SMM_BIT_DESC    *BitDesc,
+  CONST IN PCH_SMM_SOURCE_DESC *Src
+  )
+{
+  BOOLEAN IsEqual;
+  UINTN   DescIndex;
+
+  IsEqual = FALSE;
+
+  for (DescIndex = 0; DescIndex < NUM_EN_BITS; ++DescIndex) {
+    if ((BitDesc->Reg.Type == Src->En[DescIndex].Reg.Type) &&
+        (BitDesc->Reg.Data.raw == Src->En[DescIndex].Reg.Data.raw) &&
+        (BitDesc->Bit == Src->En[DescIndex].Bit)) {
+      IsEqual = TRUE;
+      break;
+    }
+  }
+  return IsEqual;
+}
+
+/**
+  Compare 2 SMM source descriptors' statuses.
+
+  @param[in] Src1                 Pointer to the PCH SMI source description table 1
+  @param[in] Src2                 Pointer to the PCH SMI source description table 2
+
+  @retval TRUE                    The statuses of the 2 SMM source descriptors are identical.
+  @retval FALSE                   The statuses of the 2 SMM source descriptors are not identical.
+**/
+BOOLEAN
+CompareStatuses (
+  CONST IN PCH_SMM_SOURCE_DESC *Src1,
+  CONST IN PCH_SMM_SOURCE_DESC *Src2
+  )
+{
+  BOOLEAN IsEqual;
+  UINTN   DescIndex;
+
+  IsEqual = TRUE;
+
+  for (DescIndex = 0; DescIndex < NUM_STS_BITS; DescIndex++) {
+    ///
+    /// It's okay to compare a NULL bit description to a non-NULL bit description.
+    /// They are unequal and these tests will generate the correct result.
+    ///
+    if (Src1->Sts[DescIndex].Bit != Src2->Sts[DescIndex].Bit ||
+        Src1->Sts[DescIndex].Reg.Type != Src2->Sts[DescIndex].Reg.Type ||
+        Src1->Sts[DescIndex].Reg.Data.raw != Src2->Sts[DescIndex].Reg.Data.raw
+        ) {
+      IsEqual = FALSE;
+      break;
+      ///
+      /// out of for loop
+      ///
+    }
+  }
+
+  return IsEqual;
+}
+
+/**
+  Compare 2 SMM source descriptors, based on Enable settings and Status settings of them.
+
+  @param[in] Src1                 Pointer to the PCH SMI source description table 1
+  @param[in] Src2                 Pointer to the PCH SMI source description table 2
+
+  @retval TRUE                    The 2 SMM source descriptors are identical.
+  @retval FALSE                   The 2 SMM source descriptors are not identical.
+**/
+BOOLEAN
+CompareSources (
+  CONST IN PCH_SMM_SOURCE_DESC *Src1,
+  CONST IN PCH_SMM_SOURCE_DESC *Src2
+  )
+{
+  return (BOOLEAN) (CompareEnables (Src1, Src2) && CompareStatuses (Src1, Src2));
+}
+
+/**
+  Check if an SMM source is active.
+
+  @param[in] Src                  Pointer to the PCH SMI source description table
+  @param[in] SciEn                Indicate if SCI is enabled or not
+  @param[in] SmiEnValue           Value from R_ACPI_IO_SMI_EN
+  @param[in] SmiStsValue          Value from R_ACPI_IO_SMI_STS
+
+  @retval TRUE                    It is active.
+  @retval FALSE                   It is inactive.
+**/
+BOOLEAN
+SourceIsActive (
+  CONST IN PCH_SMM_SOURCE_DESC  *Src,
+  CONST IN BOOLEAN              SciEn,
+  CONST IN UINT32               SmiEnValue,
+  CONST IN UINT32               SmiStsValue
+  )
+{
+  UINTN   DescIndex;
+
+  ///
+  /// This source is dependent on SciEn, and SciEn == 1.  An ACPI OS is present,
+  /// so we shouldn't do anything w/ this source until SciEn == 0.
+  ///
+  if ((Src->Flags == PCH_SMM_SCI_EN_DEPENDENT) && (SciEn)) {
+    return FALSE;
+  }
+
+  ///
+  /// Checking top level SMI status. If the status is not active, return false immediately
+  ///
+  if (!IS_BIT_DESC_NULL (Src->PmcSmiSts)) {
+    if ((Src->PmcSmiSts.Reg.Type == ACPI_ADDR_TYPE) &&
+        (Src->PmcSmiSts.Reg.Data.acpi == R_ACPI_IO_SMI_STS) &&
+        ((SmiStsValue & (1u << Src->PmcSmiSts.Bit)) == 0)) {
+      return FALSE;
+    }
+  }
+
+  ///
+  /// Read each bit desc from hardware and make sure it's a one
+  ///
+  for (DescIndex = 0; DescIndex < NUM_EN_BITS; DescIndex++) {
+    if (!IS_BIT_DESC_NULL (Src->En[DescIndex])) {
+      if ((Src->En[DescIndex].Reg.Type == ACPI_ADDR_TYPE) &&
+          (Src->En[DescIndex].Reg.Data.acpi == R_ACPI_IO_SMI_EN) &&
+          ((SmiEnValue & (1u << Src->En[DescIndex].Bit)) == 0)) {
+        return FALSE;
+      } else if (ReadBitDesc (&Src->En[DescIndex]) == 0) {
+        return FALSE;
+      }
+    }
+  }
+
+  ///
+  /// Read each bit desc from hardware and make sure it's a one
+  ///
+  for (DescIndex = 0; DescIndex < NUM_STS_BITS; DescIndex++) {
+    if (!IS_BIT_DESC_NULL (Src->Sts[DescIndex])) {
+      if ((Src->Sts[DescIndex].Reg.Type == ACPI_ADDR_TYPE) &&
+          (Src->Sts[DescIndex].Reg.Data.acpi == R_ACPI_IO_SMI_STS) &&
+          ((SmiStsValue & (1u << Src->Sts[DescIndex].Bit)) == 0)) {
+        return FALSE;
+      } else if (ReadBitDesc (&Src->Sts[DescIndex]) == 0) {
+        return FALSE;
+      }
+    }
+  }
+
+  return TRUE;
+}
+
+/**
+  Enable the SMI source event by set the SMI enable bit, this function would also clear SMI
+  status bit to make initial state is correct
+
+  @param[in] SrcDesc              Pointer to the PCH SMI source description table
+
+**/
+VOID
+PchSmmEnableSource (
+  CONST PCH_SMM_SOURCE_DESC *SrcDesc
+  )
+{
+  UINTN DescIndex;
+
+  ///
+  /// Set enables to 1 by writing a 1
+  ///
+  for (DescIndex = 0; DescIndex < NUM_EN_BITS; DescIndex++) {
+    if (!IS_BIT_DESC_NULL (SrcDesc->En[DescIndex])) {
+      WriteBitDesc (&SrcDesc->En[DescIndex], 1, FALSE);
+    }
+  }
+  ///
+  /// Clear statuses to 0 by writing a 1
+  ///
+  for (DescIndex = 0; DescIndex < NUM_STS_BITS; DescIndex++) {
+    if (!IS_BIT_DESC_NULL (SrcDesc->Sts[DescIndex])) {
+      WriteBitDesc (&SrcDesc->Sts[DescIndex], 1, TRUE);
+    }
+  }
+}
+
+/**
+  Disable the SMI source event by clear the SMI enable bit
+
+  @param[in] SrcDesc              Pointer to the PCH SMI source description table
+
+**/
+VOID
+PchSmmDisableSource (
+  CONST PCH_SMM_SOURCE_DESC *SrcDesc
+  )
+{
+  UINTN DescIndex;
+
+  for (DescIndex = 0; DescIndex < NUM_EN_BITS; DescIndex++) {
+    if (!IS_BIT_DESC_NULL (SrcDesc->En[DescIndex])) {
+      WriteBitDesc (&SrcDesc->En[DescIndex], 0, FALSE);
+    }
+  }
+}
+
+/**
+  Clear the SMI status bit by set the source bit of SMI status register
+
+  @param[in] SrcDesc              Pointer to the PCH SMI source description table
+
+**/
+VOID
+PchSmmClearSource (
+  CONST PCH_SMM_SOURCE_DESC *SrcDesc
+  )
+{
+  UINTN DescIndex;
+
+  for (DescIndex = 0; DescIndex < NUM_STS_BITS; DescIndex++) {
+    if (!IS_BIT_DESC_NULL (SrcDesc->Sts[DescIndex])) {
+      WriteBitDesc (&SrcDesc->Sts[DescIndex], 1, TRUE);
+    }
+  }
+}
+
+/**
+  Sets the source to a 1 and then waits for it to clear.
+  Be very careful when calling this function -- it will not
+  ASSERT.  An acceptable case to call the function is when
+  waiting for the NEWCENTURY_STS bit to clear (which takes
+  3 RTCCLKs).
+
+  @param[in] SrcDesc              Pointer to the PCH SMI source description table
+
+**/
+VOID
+PchSmmClearSourceAndBlock (
+  CONST PCH_SMM_SOURCE_DESC *SrcDesc
+  )
+{
+  UINTN   DescIndex;
+  BOOLEAN IsSet;
+
+  for (DescIndex = 0; DescIndex < NUM_STS_BITS; DescIndex++) {
+
+    if (!IS_BIT_DESC_NULL (SrcDesc->Sts[DescIndex])) {
+      ///
+      /// Write the bit
+      ///
+      WriteBitDesc (&SrcDesc->Sts[DescIndex], 1, TRUE);
+
+      ///
+      /// Don't return until the bit actually clears.
+      ///
+      IsSet = TRUE;
+      while (IsSet) {
+        IsSet = ReadBitDesc (&SrcDesc->Sts[DescIndex]);
+        ///
+        /// IsSet will eventually clear -- or else we'll have
+        /// an infinite loop.
+        ///
+      }
+    }
+  }
+}
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.h
new file mode 100644
index 0000000000..db7713fa02
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmHelpers.h
@@ -0,0 +1,155 @@
+/** @file
+  Helper functions for PCH SMM
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef PCH_SMM_HELPERS_H
+#define PCH_SMM_HELPERS_H
+
+#include "PchSmm.h"
+#include "PchxSmmHelpers.h"
+//
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// SUPPORT / HELPER FUNCTIONS (PCH version-independent)
+//
+
+/**
+  Publish SMI Dispatch protocols.
+
+
+**/
+VOID
+PchSmmPublishDispatchProtocols (
+  VOID
+  );
+
+/**
+  Compare 2 SMM source descriptors' enable settings.
+
+  @param[in] Src1                 Pointer to the PCH SMI source description table 1
+  @param[in] Src2                 Pointer to the PCH SMI source description table 2
+
+  @retval TRUE                    The enable settings of the 2 SMM source descriptors are identical.
+  @retval FALSE                   The enable settings of the 2 SMM source descriptors are not identical.
+**/
+BOOLEAN
+CompareEnables (
+  CONST IN PCH_SMM_SOURCE_DESC *Src1,
+  CONST IN PCH_SMM_SOURCE_DESC *Src2
+  );
+
+/**
+  Compare a bit descriptor to the enables of source descriptor. Includes null address type.
+
+  @param[in] BitDesc              Pointer to the PCH SMI bit descriptor
+  @param[in] Src                  Pointer to the PCH SMI source description table 2
+
+  @retval TRUE                    The bit desc is equal to any of the enables in source descriptor
+  @retval FALSE                   The bid desc is not equal to all of the enables in source descriptor
+**/
+BOOLEAN
+IsBitEqualToAnySourceEn (
+  CONST IN PCH_SMM_BIT_DESC    *BitDesc,
+  CONST IN PCH_SMM_SOURCE_DESC *Src
+  );
+
+/**
+  Compare 2 SMM source descriptors' statuses.
+
+  @param[in] Src1                 Pointer to the PCH SMI source description table 1
+  @param[in] Src2                 Pointer to the PCH SMI source description table 2
+
+  @retval TRUE                    The statuses of the 2 SMM source descriptors are identical.
+  @retval FALSE                   The statuses of the 2 SMM source descriptors are not identical.
+**/
+BOOLEAN
+CompareStatuses (
+  CONST IN PCH_SMM_SOURCE_DESC *Src1,
+  CONST IN PCH_SMM_SOURCE_DESC *Src2
+  );
+
+/**
+  Compare 2 SMM source descriptors, based on Enable settings and Status settings of them.
+
+  @param[in] Src1                 Pointer to the PCH SMI source description table 1
+  @param[in] Src2                 Pointer to the PCH SMI source description table 2
+
+  @retval TRUE                    The 2 SMM source descriptors are identical.
+  @retval FALSE                   The 2 SMM source descriptors are not identical.
+**/
+BOOLEAN
+CompareSources (
+  CONST IN PCH_SMM_SOURCE_DESC *Src1,
+  CONST IN PCH_SMM_SOURCE_DESC *Src2
+  );
+
+/**
+  Check if an SMM source is active.
+
+  @param[in] Src                  Pointer to the PCH SMI source description table
+  @param[in] SciEn                Indicate if SCI is enabled or not
+  @param[in] SmiEnValue           Value from R_PCH_SMI_EN
+  @param[in] SmiStsValue          Value from R_PCH_SMI_STS
+
+  @retval TRUE                    It is active.
+  @retval FALSE                   It is inactive.
+**/
+BOOLEAN
+SourceIsActive (
+  CONST IN PCH_SMM_SOURCE_DESC  *Src,
+  CONST IN BOOLEAN              SciEn,
+  CONST IN UINT32               SmiEnValue,
+  CONST IN UINT32               SmiStsValue
+  );
+
+/**
+  Enable the SMI source event by set the SMI enable bit, this function would also clear SMI
+  status bit to make initial state is correct
+
+  @param[in] SrcDesc              Pointer to the PCH SMI source description table
+
+**/
+VOID
+PchSmmEnableSource (
+  CONST PCH_SMM_SOURCE_DESC *SrcDesc
+  );
+
+/**
+  Disable the SMI source event by clear the SMI enable bit
+
+  @param[in] SrcDesc              Pointer to the PCH SMI source description table
+
+**/
+VOID
+PchSmmDisableSource (
+  CONST PCH_SMM_SOURCE_DESC *SrcDesc
+  );
+
+/**
+  Clear the SMI status bit by set the source bit of SMI status register
+
+  @param[in] SrcDesc              Pointer to the PCH SMI source description table
+
+**/
+VOID
+PchSmmClearSource (
+  CONST PCH_SMM_SOURCE_DESC *SrcDesc
+  );
+
+/**
+  Sets the source to a 1 and then waits for it to clear.
+  Be very careful when calling this function -- it will not
+  ASSERT.  An acceptable case to call the function is when
+  waiting for the NEWCENTURY_STS bit to clear (which takes
+  3 RTCCLKs).
+
+  @param[in] SrcDesc              Pointer to the PCH SMI source description table
+
+**/
+VOID
+PchSmmClearSourceAndBlock (
+  CONST PCH_SMM_SOURCE_DESC *SrcDesc
+  );
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPeriodicTimer.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPeriodicTimer.c
new file mode 100644
index 0000000000..3c3e638cbf
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPeriodicTimer.c
@@ -0,0 +1,667 @@
+/** @file
+  File to contain all the hardware specific stuff for the Periodical Timer dispatch protocol.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "PchSmmHelpers.h"
+#include <Protocol/PchSmmPeriodicTimerControl.h>
+#include <Library/PmcPrivateLib.h>
+
+//
+// There is only one instance for PeriodicTimerCommBuffer.
+// It's safe in SMM since there is no re-entry for the function.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_SMM_PERIODIC_TIMER_CONTEXT          mPchPeriodicTimerCommBuffer;
+
+typedef enum {
+  PERIODIC_TIMER= 0,
+  SWSMI_TIMER,
+  NUM_TIMERS
+} SUPPORTED_TIMER;
+
+typedef struct _TIMER_INTERVAL {
+  UINT64  Interval;
+  UINT8   AssociatedTimer;
+} TIMER_INTERVAL;
+
+#define NUM_INTERVALS 8
+
+//
+// Time constants, in 100 nano-second units
+//
+#define TIME_64s    640000000 ///< 64   s
+#define TIME_32s    320000000 ///< 32   s
+#define TIME_16s    160000000 ///< 16   s
+#define TIME_8s     80000000  ///<  8   s
+#define TIME_64ms   640000    ///< 64   ms
+#define TIME_32ms   320000    ///< 32   ms
+#define TIME_16ms   160000    ///< 16   ms
+#define TIME_1_5ms  15000     ///< 1.5  ms
+
+typedef enum {
+  INDEX_TIME_64s  = 0,
+  INDEX_TIME_32s,
+  INDEX_TIME_16s,
+  INDEX_TIME_8s,
+  INDEX_TIME_64ms,
+  INDEX_TIME_32ms,
+  INDEX_TIME_16ms,
+  INDEX_TIME_1_5ms,
+  INDEX_TIME_MAX
+} TIMER_INTERVAL_INDEX;
+
+static TIMER_INTERVAL mSmmPeriodicTimerIntervals[NUM_INTERVALS] = {
+  {
+    TIME_64s,
+    PERIODIC_TIMER
+  },
+  {
+    TIME_32s,
+    PERIODIC_TIMER
+  },
+  {
+    TIME_16s,
+    PERIODIC_TIMER
+  },
+  {
+    TIME_8s,
+    PERIODIC_TIMER
+  },
+  {
+    TIME_64ms,
+    SWSMI_TIMER
+  },
+  {
+    TIME_32ms,
+    SWSMI_TIMER
+  },
+  {
+    TIME_16ms,
+    SWSMI_TIMER
+  },
+  {
+    TIME_1_5ms,
+    SWSMI_TIMER
+  },
+};
+
+typedef struct _TIMER_INFO {
+  UINTN   NumChildren;        ///< number of children using this timer
+  UINT64  MinReqInterval;     ///< minimum interval required by children
+  UINTN   CurrentSetting;     ///< interval this timer is set at right now (index into interval table)
+} TIMER_INFO;
+
+GLOBAL_REMOVE_IF_UNREFERENCED TIMER_INFO          mTimers[NUM_TIMERS];
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mTimerSourceDesc[NUM_TIMERS] = {
+  {
+    PCH_SMM_NO_FLAGS,
+    {
+      {
+        {
+          ACPI_ADDR_TYPE,
+          {R_ACPI_IO_SMI_EN}
+        },
+        S_ACPI_IO_SMI_EN,
+        N_ACPI_IO_SMI_EN_PERIODIC
+      },
+      NULL_BIT_DESC_INITIALIZER
+    },
+    {
+      {
+        {
+          ACPI_ADDR_TYPE,
+          {R_ACPI_IO_SMI_STS}
+        },
+        S_ACPI_IO_SMI_STS,
+        N_ACPI_IO_SMI_STS_PERIODIC
+      }
+    },
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_STS}
+      },
+      S_ACPI_IO_SMI_STS,
+      N_ACPI_IO_SMI_STS_PERIODIC
+    }
+  },
+  {
+    PCH_SMM_NO_FLAGS,
+    {
+      {
+        {
+          ACPI_ADDR_TYPE,
+          {R_ACPI_IO_SMI_EN}
+        },
+        S_ACPI_IO_SMI_EN,
+        N_ACPI_IO_SMI_EN_SWSMI_TMR
+      },
+      NULL_BIT_DESC_INITIALIZER
+    },
+    {
+      {
+        {
+          ACPI_ADDR_TYPE,
+          {R_ACPI_IO_SMI_STS}
+        },
+        S_ACPI_IO_SMI_STS,
+        N_ACPI_IO_SMI_STS_SWSMI_TMR
+      }
+    },
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_STS}
+      },
+      S_ACPI_IO_SMI_STS,
+      N_ACPI_IO_SMI_STS_SWSMI_TMR
+    }
+  }
+};
+
+/**
+  Program Smm Periodic Timer
+
+  @param[in] SrcDesc              Pointer to the PCH_SMM_SOURCE_DESC instance.
+**/
+VOID
+PchSmmPeriodicTimerProgramTimers (
+  IN CONST PCH_SMM_SOURCE_DESC    *SrcDesc
+  );
+
+/**
+  Convert the dispatch context to the timer interval, this function will assert if then either:
+  (1) The context contains an invalid interval
+  (2) The timer interval table is corrupt
+
+  @param[in] DispatchContext      The pointer to the Dispatch Context
+
+  @retval TIMER_INTERVAL          The timer interval of input dispatch context
+**/
+TIMER_INTERVAL *
+ContextToTimerInterval (
+  IN  PCH_SMM_CONTEXT     *DispatchContext
+  )
+{
+  UINTN loopvar;
+
+  ///
+  /// Determine which timer this child is using
+  ///
+  for (loopvar = 0; loopvar < NUM_INTERVALS; loopvar++) {
+    if (((DispatchContext->PeriodicTimer.SmiTickInterval == 0) &&
+         (DispatchContext->PeriodicTimer.Period >= mSmmPeriodicTimerIntervals[loopvar].Interval)) ||
+        (DispatchContext->PeriodicTimer.SmiTickInterval == mSmmPeriodicTimerIntervals[loopvar].Interval)) {
+      return &mSmmPeriodicTimerIntervals[loopvar];
+    }
+  }
+  ///
+  /// If this assertion fires, then either:
+  ///    (1) the context contains an invalid interval
+  ///    (2) the timer interval table is corrupt
+  ///
+  ASSERT (FALSE);
+
+  return NULL;
+}
+
+/**
+  Figure out which timer the child is requesting and
+  send back the source description
+
+  @param[in] DispatchContext      The pointer to the Dispatch Context instances
+  @param[out] SrcDesc             The pointer to the source description
+
+**/
+VOID
+MapPeriodicTimerToSrcDesc (
+  IN  PCH_SMM_CONTEXT             *DispatchContext,
+  OUT PCH_SMM_SOURCE_DESC         *SrcDesc
+  )
+{
+  TIMER_INTERVAL  *TimerInterval;
+
+  ///
+  /// Figure out which timer the child is requesting and
+  /// send back the source description
+  ///
+  TimerInterval = ContextToTimerInterval (DispatchContext);
+  if (TimerInterval == NULL) {
+    return;
+  }
+
+  CopyMem (
+    (VOID *) SrcDesc,
+    (VOID *) (&mTimerSourceDesc[TimerInterval->AssociatedTimer]),
+    sizeof (PCH_SMM_SOURCE_DESC)
+    );
+
+  ///
+  /// Program the value of the interval into hardware
+  ///
+  PchSmmPeriodicTimerProgramTimers (SrcDesc);
+}
+
+/**
+  Update the elapsed time from the Interval data of DATABASE_RECORD
+
+  @param[in] Record               The pointer to the DATABASE_RECORD.
+  @param[out] HwContext           The Context to be updated.
+
+**/
+VOID
+EFIAPI
+PeriodicTimerGetContext (
+  IN  DATABASE_RECORD    *Record,
+  OUT PCH_SMM_CONTEXT    *HwContext
+  )
+{
+  TIMER_INTERVAL  *TimerInterval;
+
+  ASSERT (Record->ProtocolType == PeriodicTimerType);
+
+  TimerInterval = ContextToTimerInterval (&Record->ChildContext);
+  if (TimerInterval == NULL) {
+    return;
+  }
+  ///
+  /// Ignore the hardware context. It's not required for this protocol.
+  /// Instead, just increment the child's context.
+  /// Update the elapsed time w/ the data from our tables
+  ///
+  Record->MiscData.ElapsedTime += mTimers[TimerInterval->AssociatedTimer].MinReqInterval;
+  *HwContext = Record->ChildContext;
+}
+
+/**
+  Check whether Periodic Timer of two contexts match
+
+  @param[in] Context1             Context 1 that includes Periodic Timer  1
+  @param[in] Context2             Context 2 that includes Periodic Timer  2
+
+  @retval FALSE                   Periodic Timer match
+  @retval TRUE                    Periodic Timer don't match
+**/
+BOOLEAN
+EFIAPI
+PeriodicTimerCmpContext (
+  IN PCH_SMM_CONTEXT     *HwContext,
+  IN PCH_SMM_CONTEXT     *ChildContext
+  )
+{
+  DATABASE_RECORD        *Record;
+  Record = DATABASE_RECORD_FROM_CHILDCONTEXT (ChildContext);
+
+  if (!Record->MiscData.TimerSmiEnabled) {
+    return FALSE;
+  }
+  if (Record->MiscData.ElapsedTime >= ChildContext->PeriodicTimer.Period) {
+    ///
+    /// For EDKII, the ElapsedTime is reset when PeriodicTimerGetCommBuffer
+    ///
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
+
+/**
+  Gather the CommBuffer information of SmmPeriodicTimerDispatch2.
+
+  @param[in]  Record              No use
+  @param[out] CommBuffer          Point to the CommBuffer structure
+  @param[out] CommBufferSize      Point to the Size of CommBuffer structure
+
+**/
+VOID
+EFIAPI
+PeriodicTimerGetCommBuffer (
+  IN  DATABASE_RECORD    *Record,
+  OUT VOID               **CommBuffer,
+  OUT UINTN              *CommBufferSize
+  )
+{
+  ASSERT (Record->ProtocolType == PeriodicTimerType);
+
+  mPchPeriodicTimerCommBuffer.ElapsedTime = Record->MiscData.ElapsedTime;
+
+  ///
+  /// For EDKII, the ElapsedTime is reset here
+  ///
+  Record->MiscData.ElapsedTime = 0;
+
+  ///
+  /// Return the CommBuffer
+  ///
+  *CommBuffer = (VOID *) &mPchPeriodicTimerCommBuffer;
+  *CommBufferSize = sizeof (EFI_SMM_PERIODIC_TIMER_CONTEXT);
+}
+
+/**
+  Program Smm Periodic Timer
+
+  @param[in] SrcDesc              Pointer to the PCH_SMM_SOURCE_DESC instance.
+**/
+VOID
+PchSmmPeriodicTimerProgramTimers (
+  IN CONST PCH_SMM_SOURCE_DESC    *SrcDesc
+  )
+{
+  SUPPORTED_TIMER Timer;
+  DATABASE_RECORD *RecordInDb;
+  LIST_ENTRY      *LinkInDb;
+  TIMER_INTERVAL  *TimerInterval;
+
+  ///
+  /// Find the minimum required interval for each timer
+  ///
+  for (Timer = 0; Timer < NUM_TIMERS; Timer++) {
+    mTimers[Timer].MinReqInterval = ~ (UINT64) 0x0;
+    mTimers[Timer].NumChildren    = 0;
+  }
+
+  LinkInDb = GetFirstNode (&mPrivateData.CallbackDataBase);
+  while (!IsNull (&mPrivateData.CallbackDataBase, LinkInDb)) {
+    RecordInDb = DATABASE_RECORD_FROM_LINK (LinkInDb);
+    if (RecordInDb->ProtocolType == PeriodicTimerType) {
+      if (RecordInDb->MiscData.TimerSmiEnabled) {
+        ///
+        /// This child is registerd with the PeriodicTimer protocol
+        ///
+        TimerInterval = ContextToTimerInterval (&RecordInDb->ChildContext);
+        if (TimerInterval == NULL) {
+          return;
+        }
+
+        Timer = TimerInterval->AssociatedTimer;
+        if (Timer < 0 || Timer >= NUM_TIMERS) {
+          ASSERT (FALSE);
+          CpuDeadLoop ();
+          return;
+        }
+        if (mTimers[Timer].MinReqInterval > RecordInDb->ChildContext.PeriodicTimer.SmiTickInterval) {
+          mTimers[Timer].MinReqInterval = RecordInDb->ChildContext.PeriodicTimer.SmiTickInterval;
+        }
+        mTimers[Timer].NumChildren++;
+      }
+    }
+    LinkInDb = GetNextNode (&mPrivateData.CallbackDataBase, &RecordInDb->Link);
+  }
+  ///
+  /// Program the hardware
+  ///
+  if (mTimers[PERIODIC_TIMER].NumChildren > 0) {
+    switch (mTimers[PERIODIC_TIMER].MinReqInterval) {
+      case TIME_64s:
+        PmcSetPeriodicSmiRate (PmcPeriodicSmiRate64s);
+        mTimers[PERIODIC_TIMER].CurrentSetting = INDEX_TIME_64s;
+        break;
+
+      case TIME_32s:
+        PmcSetPeriodicSmiRate (PmcPeriodicSmiRate32s);
+        mTimers[PERIODIC_TIMER].CurrentSetting = INDEX_TIME_32s;
+        break;
+
+      case TIME_16s:
+        PmcSetPeriodicSmiRate (PmcPeriodicSmiRate16s);
+        mTimers[PERIODIC_TIMER].CurrentSetting = INDEX_TIME_16s;
+        break;
+
+      case TIME_8s:
+        PmcSetPeriodicSmiRate (PmcPeriodicSmiRate8s);
+        mTimers[PERIODIC_TIMER].CurrentSetting = INDEX_TIME_8s;
+        break;
+
+      default:
+        ASSERT (FALSE);
+        break;
+    }
+
+    ///
+    /// Restart the timer here, just need to clear the SMI
+    ///
+    if (SrcDesc->Sts[0].Bit == N_ACPI_IO_SMI_STS_PERIODIC) {
+      PchSmmClearSource (&mTimerSourceDesc[PERIODIC_TIMER]);
+    }
+  } else {
+    PchSmmDisableSource (&mTimerSourceDesc[PERIODIC_TIMER]);
+  }
+
+  if (mTimers[SWSMI_TIMER].NumChildren > 0) {
+    switch (mTimers[SWSMI_TIMER].MinReqInterval) {
+      case TIME_64ms:
+        PmcSetSwSmiRate (PmcSwSmiRate64ms);
+        mTimers[SWSMI_TIMER].CurrentSetting = INDEX_TIME_64ms;
+        break;
+
+      case TIME_32ms:
+        PmcSetSwSmiRate (PmcSwSmiRate32ms);
+        mTimers[SWSMI_TIMER].CurrentSetting = INDEX_TIME_32ms;
+        break;
+
+      case TIME_16ms:
+        PmcSetSwSmiRate (PmcSwSmiRate16ms);
+        mTimers[SWSMI_TIMER].CurrentSetting = INDEX_TIME_16ms;
+        break;
+
+      case TIME_1_5ms:
+        PmcSetSwSmiRate (PmcSwSmiRate1p5ms);
+        mTimers[SWSMI_TIMER].CurrentSetting = INDEX_TIME_1_5ms;
+        break;
+
+      default:
+        ASSERT (FALSE);
+        break;
+    }
+
+    ///
+    /// Restart the timer here, need to disable, clear, then enable to restart this timer
+    ///
+    if (SrcDesc->Sts[0].Bit == N_ACPI_IO_SMI_STS_SWSMI_TMR) {
+      PchSmmDisableSource (&mTimerSourceDesc[SWSMI_TIMER]);
+      PchSmmClearSource (&mTimerSourceDesc[SWSMI_TIMER]);
+      PchSmmEnableSource (&mTimerSourceDesc[SWSMI_TIMER]);
+    }
+  } else {
+    PchSmmDisableSource (&mTimerSourceDesc[SWSMI_TIMER]);
+  }
+}
+
+/**
+  This services returns the next SMI tick period that is supported by the chipset.
+  The order returned is from longest to shortest interval period.
+
+  @param[in] This                 Pointer to the EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL instance.
+  @param[in, out] SmiTickInterval Pointer to pointer of the next shorter SMI interval period that is supported by the child.
+
+  @retval EFI_SUCCESS             The service returned successfully.
+  @retval EFI_INVALID_PARAMETER   The parameter SmiTickInterval is invalid.
+**/
+EFI_STATUS
+PchSmmPeriodicTimerDispatchGetNextShorterInterval (
+  IN CONST EFI_SMM_PERIODIC_TIMER_DISPATCH2_PROTOCOL  *This,
+  IN OUT   UINT64                                     **SmiTickInterval
+  )
+{
+  TIMER_INTERVAL  *IntervalPointer;
+
+  ASSERT (SmiTickInterval != NULL);
+
+  IntervalPointer = (TIMER_INTERVAL *) *SmiTickInterval;
+
+  if (IntervalPointer == NULL) {
+    ///
+    /// The first time child requesting an interval
+    ///
+    IntervalPointer = &mSmmPeriodicTimerIntervals[0];
+  } else if (IntervalPointer == &mSmmPeriodicTimerIntervals[NUM_INTERVALS - 1]) {
+    ///
+    /// At end of the list
+    ///
+    IntervalPointer = NULL;
+  } else {
+    if ((IntervalPointer >= &mSmmPeriodicTimerIntervals[0]) &&
+        (IntervalPointer < &mSmmPeriodicTimerIntervals[NUM_INTERVALS - 1])
+        ) {
+      ///
+      /// Get the next interval in the list
+      ///
+      IntervalPointer++;
+    } else {
+      ///
+      /// Input is out of range
+      ///
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  if (IntervalPointer != NULL) {
+    *SmiTickInterval = &IntervalPointer->Interval;
+  } else {
+    *SmiTickInterval = NULL;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function is responsible for calculating and enabling any timers that are required
+  to dispatch messages to children. The SrcDesc argument isn't acutally used.
+
+  @param[in] SrcDesc              Pointer to the PCH_SMM_SOURCE_DESC instance.
+
+**/
+VOID
+EFIAPI
+PchSmmPeriodicTimerClearSource (
+  IN CONST PCH_SMM_SOURCE_DESC    *SrcDesc
+  )
+{
+  PchSmmPeriodicTimerProgramTimers (SrcDesc);
+}
+
+
+/**
+  Check if the handle is in type of PeriodicTimer
+
+  @retval TRUE                          The handle is in type of PeriodicTimer.
+  @retval FALSE                         The handle is not in type of PeriodicTimer.
+**/
+BOOLEAN
+IsSmmPeriodicTimerHandle (
+  IN EFI_HANDLE                         DispatchHandle
+  )
+{
+  DATABASE_RECORD                       *RecordInDb;
+  LIST_ENTRY                            *LinkInDb;
+
+  LinkInDb = GetFirstNode (&mPrivateData.CallbackDataBase);
+  while (!IsNull (&mPrivateData.CallbackDataBase, LinkInDb)) {
+    if (DispatchHandle == (EFI_HANDLE) LinkInDb) {
+      RecordInDb = DATABASE_RECORD_FROM_LINK (LinkInDb);
+      if (RecordInDb->ProtocolType == PeriodicTimerType) {
+        return TRUE;
+      }
+    }
+    LinkInDb = GetNextNode (&mPrivateData.CallbackDataBase, LinkInDb);
+  }
+  return FALSE;
+}
+
+/**
+  Pause SMM periodic timer callback function.
+
+  This function disable the SMI enable of SMI timer according to the DispatchHandle,
+  which is returned by SMM periodic timer callback registration.
+
+  @retval EFI_SUCCESS                   This operation is complete.
+  @retval EFI_INVALID_PARAMETER         The DispatchHandle is invalid.
+**/
+EFI_STATUS
+EFIAPI
+PchSmmPeriodicTimerControlPause (
+  IN PCH_SMM_PERIODIC_TIMER_CONTROL_PROTOCOL      *This,
+  IN EFI_HANDLE                                   DispatchHandle
+  )
+{
+  DATABASE_RECORD                       *RecordInDb;
+
+  if (IsSmmPeriodicTimerHandle (DispatchHandle) == FALSE) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  RecordInDb = DATABASE_RECORD_FROM_LINK (DispatchHandle);
+  RecordInDb->MiscData.TimerSmiEnabled = FALSE;
+  //
+  // reset the timer interval per SMI trigger due to stop a periodic timer SMI
+  //
+  PchSmmPeriodicTimerProgramTimers (&RecordInDb->SrcDesc);
+  return EFI_SUCCESS;
+}
+
+/**
+  Resume SMM periodic timer callback function.
+
+  This function enable the SMI enable of SMI timer according to the DispatchHandle,
+  which is returned by SMM periodic timer callback registration.
+
+  @retval EFI_SUCCESS                   This operation is complete.
+  @retval EFI_INVALID_PARAMETER         The DispatchHandle is invalid.
+**/
+EFI_STATUS
+EFIAPI
+PchSmmPeriodicTimerControlResume (
+  IN PCH_SMM_PERIODIC_TIMER_CONTROL_PROTOCOL      *This,
+  IN EFI_HANDLE                                   DispatchHandle
+  )
+{
+  DATABASE_RECORD                       *RecordInDb;
+
+  if (IsSmmPeriodicTimerHandle (DispatchHandle) == FALSE) {
+    return EFI_INVALID_PARAMETER;
+  }
+  RecordInDb = DATABASE_RECORD_FROM_LINK (DispatchHandle);
+  RecordInDb->MiscData.TimerSmiEnabled = TRUE;
+  //
+  // reset the timer interval per SMI trigger due to resume a periodic timer SMI
+  //
+  PchSmmPeriodicTimerProgramTimers (&RecordInDb->SrcDesc);
+  return EFI_SUCCESS;
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_SMM_PERIODIC_TIMER_CONTROL_PROTOCOL mPchSmmPeriodicTimerControlProtocol = {
+  PchSmmPeriodicTimerControlPause,
+  PchSmmPeriodicTimerControlResume
+};
+
+/**
+  Install PCH SMM periodic timer control protocol
+
+  @param[in] Handle                     handle for this driver
+
+  @retval EFI_SUCCESS                   Driver initialization completed successfully
+**/
+EFI_STATUS
+EFIAPI
+InstallPchSmmPeriodicTimerControlProtocol (
+  IN EFI_HANDLE                         Handle
+  )
+{
+  EFI_STATUS                            Status;
+
+  //
+  // Install protocol interface
+  //
+  Status = gSmst->SmmInstallProtocolInterface (
+                    &Handle,
+                    &gPchSmmPeriodicTimerControlGuid,
+                    EFI_NATIVE_INTERFACE,
+                    &mPchSmmPeriodicTimerControlProtocol
+                    );
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPowerButton.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPowerButton.c
new file mode 100644
index 0000000000..bfed944848
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmPowerButton.c
@@ -0,0 +1,81 @@
+/** @file
+  File to contain all the hardware specific stuff for the Smm Power Button dispatch protocol.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <PchSmmHelpers.h>
+#include <Library/PmcPrivateLib.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mPowerButtonSourceDesc = {
+  PCH_SMM_SCI_EN_DEPENDENT,
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_PM1_EN}
+      },
+      S_ACPI_IO_PM1_EN,
+      N_ACPI_IO_PM1_EN_PWRBTN
+    },
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_PM1_STS}
+      },
+      S_ACPI_IO_PM1_STS,
+      N_ACPI_IO_PM1_STS_PWRBTN
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_PM1_STS_REG
+  }
+};
+
+/**
+  Get the power button status.
+
+  @param[in] Record               The pointer to the DATABASE_RECORD.
+  @param[out] Context             Calling context from the hardware, will be updated with the current power button status.
+
+**/
+VOID
+EFIAPI
+PowerButtonGetContext (
+  IN  DATABASE_RECORD    *Record,
+  OUT PCH_SMM_CONTEXT    *Context
+  )
+{
+  if (PmcGetPwrBtnLevel ()) {
+    Context->PowerButton.Phase = EfiPowerButtonExit;
+  } else {
+    Context->PowerButton.Phase = EfiPowerButtonEntry;
+  }
+}
+
+/**
+  Check whether Power Button status of two contexts match
+
+  @param[in] Context1             Context 1 that includes Power Button status 1
+  @param[in] Context2             Context 2 that includes Power Button status 2
+
+  @retval FALSE                   Power Button status match
+  @retval TRUE                    Power Button status don't match
+**/
+BOOLEAN
+EFIAPI
+PowerButtonCmpContext (
+  IN PCH_SMM_CONTEXT     *Context1,
+  IN PCH_SMM_CONTEXT     *Context2
+  )
+{
+  return (BOOLEAN) (Context1->PowerButton.Phase == Context2->PowerButton.Phase);
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSw.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSw.c
new file mode 100644
index 0000000000..9b13bf6308
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSw.c
@@ -0,0 +1,381 @@
+/** @file
+  File to contain all the hardware specific stuff for the Smm Sw dispatch protocol.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "PchSmmHelpers.h"
+#include <Protocol/SmmCpu.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/PmcRegs.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_SMM_CPU_PROTOCOL          *mSmmCpuProtocol;
+
+STATIC LIST_ENTRY                       mSwSmiCallbackDataBase;
+
+//
+// "SWSMI" RECORD
+// Linked list data structures
+//
+#define SW_SMI_RECORD_SIGNATURE         SIGNATURE_32 ('S', 'W', 'S', 'M')
+
+#define SW_SMI_RECORD_FROM_LINK(_record)  CR (_record, SW_SMI_RECORD, Link, SW_SMI_RECORD_SIGNATURE)
+
+typedef struct {
+  UINT32                                Signature;
+  LIST_ENTRY                            Link;
+  EFI_SMM_SW_REGISTER_CONTEXT           Context;
+  EFI_SMM_HANDLER_ENTRY_POINT2          Callback;
+} SW_SMI_RECORD;
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mSwSourceDesc = {
+  PCH_SMM_NO_FLAGS,
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_EN}
+      },
+      S_ACPI_IO_SMI_EN,
+      N_ACPI_IO_SMI_EN_APMC
+    },
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_STS}
+      },
+      S_ACPI_IO_SMI_STS,
+      N_ACPI_IO_SMI_STS_APM
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_APM
+  }
+};
+
+/**
+  Check the SwSmiInputValue to see if there is a duplicated one in the database
+
+  @param[in] SwSmiInputValue      SwSmiInputValue
+
+  @retval EFI_SUCCESS             There is no duplicated SwSmiInputValue
+  @retval EFI_INVALID_PARAMETER   There is a duplicated SwSmiInputValue
+**/
+EFI_STATUS
+SmiInputValueDuplicateCheck (
+  IN UINTN  SwSmiInputValue
+  )
+{
+  SW_SMI_RECORD   *SwSmiRecord;
+  LIST_ENTRY      *LinkInDb;
+
+  LinkInDb = GetFirstNode (&mSwSmiCallbackDataBase);
+  while (!IsNull (&mSwSmiCallbackDataBase, LinkInDb)) {
+    SwSmiRecord = SW_SMI_RECORD_FROM_LINK (LinkInDb);
+    if (SwSmiRecord->Context.SwSmiInputValue == SwSmiInputValue) {
+      return EFI_INVALID_PARAMETER;
+    }
+    LinkInDb = GetNextNode (&mSwSmiCallbackDataBase, &SwSmiRecord->Link);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Register a child SMI source dispatch function for the specified software SMI.
+
+  This service registers a function (DispatchFunction) which will be called when the software
+  SMI source specified by RegisterContext->SwSmiCpuIndex is detected. On return,
+  DispatchHandle contains a unique handle which may be used later to unregister the function
+  using UnRegister().
+
+  @param[in]  This                 Pointer to the EFI_SMM_SW_DISPATCH2_PROTOCOL instance.
+  @param[in]  DispatchFunction     Function to register for handler when the specified software
+                                   SMI is generated.
+  @param[in, out] RegisterContext  Pointer to the dispatch function's context.
+                                   The caller fills this context in before calling
+                                   the register function to indicate to the register
+                                   function which Software SMI input value the
+                                   dispatch function should be invoked for.
+  @param[out] DispatchHandle       Handle generated by the dispatcher to track the
+                                   function instance.
+
+  @retval EFI_SUCCESS            The dispatch function has been successfully
+                                 registered and the SMI source has been enabled.
+  @retval EFI_DEVICE_ERROR       The SW driver was unable to enable the SMI source.
+  @retval EFI_INVALID_PARAMETER  RegisterContext is invalid. The SW SMI input value
+                                 is not within a valid range or is already in use.
+  @retval EFI_OUT_OF_RESOURCES   There is not enough memory (system or SMM) to manage this
+                                 child.
+  @retval EFI_OUT_OF_RESOURCES   A unique software SMI value could not be assigned
+                                 for this dispatch.
+**/
+EFI_STATUS
+EFIAPI
+PchSwSmiRegister (
+  IN  EFI_SMM_SW_DISPATCH2_PROTOCOL       *This,
+  IN  EFI_SMM_HANDLER_ENTRY_POINT2        DispatchFunction,
+  IN  EFI_SMM_SW_REGISTER_CONTEXT         *DispatchContext,
+  OUT EFI_HANDLE                          *DispatchHandle
+  )
+{
+  EFI_STATUS       Status;
+  SW_SMI_RECORD    *SwSmiRecord;
+  UINTN            Index;
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "Register is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  //
+  // Find available SW SMI value if the input is -1
+  //
+  if (DispatchContext->SwSmiInputValue == (UINTN) -1) {
+    for (Index = 1; Index < MAXIMUM_SWI_VALUE; Index++) {
+      if (!EFI_ERROR (SmiInputValueDuplicateCheck (Index))) {
+        DispatchContext->SwSmiInputValue = Index;
+        break;
+      }
+    }
+    if (DispatchContext->SwSmiInputValue == (UINTN) -1) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+  }
+  //
+  // Check if it's a valid SW SMI value.
+  // The value must not bigger than 0xFF.
+  // And the value must not be 0xFF sincie it's used for SmmControll protocol.
+  //
+  if (DispatchContext->SwSmiInputValue >= MAXIMUM_SWI_VALUE) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (EFI_ERROR (SmiInputValueDuplicateCheck (DispatchContext->SwSmiInputValue))) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Create database record and add to database
+  //
+  Status = gSmst->SmmAllocatePool (
+                    EfiRuntimeServicesData,
+                    sizeof (SW_SMI_RECORD),
+                    (VOID **) &SwSmiRecord
+                    );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed to allocate memory for SwSmiRecord! \n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+  //
+  // Gather information about the registration request
+  //
+  SwSmiRecord->Signature               = SW_SMI_RECORD_SIGNATURE;
+  SwSmiRecord->Context.SwSmiInputValue = DispatchContext->SwSmiInputValue;
+  SwSmiRecord->Callback                = DispatchFunction;
+  //
+  // Publish the S/W SMI numbers in Serial logs used for Debug build.
+  //
+  DEBUG ((DEBUG_INFO, "SW SMI NUM %x  Sw Record at Address 0x%X\n", SwSmiRecord->Context.SwSmiInputValue, SwSmiRecord));
+
+  InsertTailList (&mSwSmiCallbackDataBase, &SwSmiRecord->Link);
+
+  //
+  // Child's handle will be the address linked list link in the record
+  //
+  *DispatchHandle = (EFI_HANDLE) (&SwSmiRecord->Link);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Unregister a child SMI source dispatch function for the specified software SMI.
+
+  This service removes the handler associated with DispatchHandle so that it will no longer be
+  called in response to a software SMI.
+
+  @param[in] This                Pointer to the EFI_SMM_SW_DISPATCH2_PROTOCOL instance.
+  @param[in] DispatchHandle      Handle of dispatch function to deregister.
+
+  @retval EFI_SUCCESS            The dispatch function has been successfully unregistered.
+  @retval EFI_INVALID_PARAMETER  The DispatchHandle was not valid.
+**/
+EFI_STATUS
+EFIAPI
+PchSwSmiUnRegister (
+  IN CONST EFI_SMM_SW_DISPATCH2_PROTOCOL  *This,
+  IN       EFI_HANDLE                     DispatchHandle
+  )
+{
+  EFI_STATUS            Status;
+  SW_SMI_RECORD         *RecordToDelete;
+
+  if (DispatchHandle == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Return access denied if the SmmReadyToLock event has been triggered
+  //
+  if (mReadyToLock == TRUE) {
+    DEBUG ((DEBUG_ERROR, "UnRegister is not allowed if the SmmReadyToLock event has been triggered! \n"));
+    return EFI_ACCESS_DENIED;
+  }
+
+  RecordToDelete = SW_SMI_RECORD_FROM_LINK (DispatchHandle);
+  //
+  // Take the entry out of the linked list
+  //
+  if (RecordToDelete->Signature != SW_SMI_RECORD_SIGNATURE) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  RemoveEntryList (&RecordToDelete->Link);
+  ZeroMem (RecordToDelete, sizeof (SW_SMI_RECORD));
+  Status = gSmst->SmmFreePool (RecordToDelete);
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Main entry point for an SMM handler dispatch or communicate-based callback.
+
+  @param[in]     DispatchHandle  The unique handle assigned to this handler by SmiHandlerRegister().
+  @param[in]     Context         Points to an optional handler context which was specified when the
+                                 handler was registered.
+  @param[in,out] CommBuffer      A pointer to a collection of data in memory that will
+                                 be conveyed from a non-SMM environment into an SMM environment.
+  @param[in,out] CommBufferSize  The size of the CommBuffer.
+
+  @retval EFI_SUCCESS                         The interrupt was handled and quiesced. No other handlers
+                                              should still be called.
+  @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED  The interrupt has been quiesced but other handlers should
+                                              still be called.
+  @retval EFI_WARN_INTERRUPT_SOURCE_PENDING   The interrupt is still pending and other handlers should still
+                                              be called.
+  @retval EFI_INTERRUPT_PENDING               The interrupt could not be quiesced.
+**/
+EFI_STATUS
+EFIAPI
+PchSwSmiDispatcher (
+  IN       EFI_HANDLE         DispatchHandle,
+  IN CONST VOID               *Context,
+  IN OUT   VOID               *CommBuffer,
+  IN OUT   UINTN              *CommBufferSize
+  )
+{
+  EFI_STATUS                            Status;
+  EFI_SMM_SAVE_STATE_IO_INFO            SmiIoInfo;
+  UINTN                                 CpuIndex;
+  SW_SMI_RECORD                         *SwSmiRecord;
+  LIST_ENTRY                            *LinkInDb;
+  EFI_SMM_SW_CONTEXT                    SwSmiCommBuffer;
+  UINTN                                 SwSmiCommBufferSize;
+
+  SwSmiCommBufferSize      = sizeof (EFI_SMM_SW_CONTEXT);
+  //
+  // The value in DataPort might not be accurate in multiple thread environment.
+  // There might be racing condition for R_PCH_IO_APM_STS port.
+  // Therefor, this is just for reference.
+  //
+  SwSmiCommBuffer.DataPort = IoRead8 (R_PCH_IO_APM_STS);
+
+  for (CpuIndex = 0; CpuIndex < gSmst->NumberOfCpus; CpuIndex++) {
+    Status = mSmmCpuProtocol->ReadSaveState (
+                                mSmmCpuProtocol,
+                                sizeof (EFI_SMM_SAVE_STATE_IO_INFO),
+                                EFI_SMM_SAVE_STATE_REGISTER_IO,
+                                CpuIndex,
+                                &SmiIoInfo
+                                );
+    //
+    // If this is not the SMI source, skip it.
+    //
+    if (EFI_ERROR (Status)) {
+      continue;
+    }
+    //
+    // If the IO address is not "BYTE" "WRITE" to "R_PCH_IO_APM_CNT (0xB2)", skip it.
+    //
+    if ((SmiIoInfo.IoPort != R_PCH_IO_APM_CNT) ||
+        (SmiIoInfo.IoType != EFI_SMM_SAVE_STATE_IO_TYPE_OUTPUT) ||
+        (SmiIoInfo.IoWidth != EFI_SMM_SAVE_STATE_IO_WIDTH_UINT8))
+    {
+      continue;
+    }
+    //
+    // If the IO data is used for SmmControl protocol, skip it.
+    //
+    if (SmiIoInfo.IoData == 0xFF) {
+      continue;
+    }
+
+    SwSmiCommBuffer.SwSmiCpuIndex = CpuIndex;
+    SwSmiCommBuffer.CommandPort   = (UINT8) SmiIoInfo.IoData;
+
+    LinkInDb = GetFirstNode (&mSwSmiCallbackDataBase);
+    while (!IsNull (&mSwSmiCallbackDataBase, LinkInDb)) {
+      SwSmiRecord = SW_SMI_RECORD_FROM_LINK (LinkInDb);
+      if (SwSmiRecord->Context.SwSmiInputValue == SmiIoInfo.IoData) {
+        SwSmiRecord->Callback ((EFI_HANDLE) &SwSmiRecord->Link, &SwSmiRecord->Context, &SwSmiCommBuffer, &SwSmiCommBufferSize);
+      }
+      LinkInDb = GetNextNode (&mSwSmiCallbackDataBase, &SwSmiRecord->Link);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Init required protocol for Pch Sw Dispatch protocol.
+**/
+VOID
+PchSwDispatchInit (
+  VOID
+  )
+{
+  EFI_STATUS                            Status;
+  EFI_HANDLE                            DispatchHandle;
+  DATABASE_RECORD                       Record;
+
+  //
+  // Locate PI SMM CPU protocol
+  //
+  Status = gSmst->SmmLocateProtocol (&gEfiSmmCpuProtocolGuid, NULL, (VOID **)&mSmmCpuProtocol);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Initialize SW SMI Callback DataBase
+  //
+  InitializeListHead (&mSwSmiCallbackDataBase);
+
+  //
+  // Insert SwSmi handler to PchSmmCore database
+  // There will always be one SwType record in PchSmmCore database
+  //
+  ZeroMem (&Record, sizeof (DATABASE_RECORD));
+  Record.Signature    = DATABASE_RECORD_SIGNATURE;
+  Record.Callback     = PchSwSmiDispatcher;
+  Record.ProtocolType = SwType;
+
+  CopyMem (&Record.SrcDesc, &mSwSourceDesc, sizeof (PCH_SMM_SOURCE_DESC));
+
+  DispatchHandle      = NULL;
+  Status = SmmCoreInsertRecord (
+             &Record,
+             &DispatchHandle
+             );
+  ASSERT_EFI_ERROR (Status);
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSx.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSx.c
new file mode 100644
index 0000000000..7d79f21dbd
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmSx.c
@@ -0,0 +1,224 @@
+/** @file
+  File to contain all the hardware specific stuff for the Smm Sx dispatch protocol.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "PchSmmHelpers.h"
+#include <Register/PmcRegs.h>
+#include <Register/PchPcieRpRegs.h>
+#include <Library/PchPciBdfLib.h>
+#include "PchSmiHelper.h"
+
+extern BOOLEAN               mS3SusStart;
+#define PROGRESS_CODE_S3_SUSPEND_END  PcdGet32 (PcdProgressCodeS3SuspendEnd)
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mSxSourceDesc = {
+  PCH_SMM_NO_FLAGS,
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_EN}
+      },
+      S_ACPI_IO_SMI_EN,
+      N_ACPI_IO_SMI_EN_ON_SLP_EN
+    },
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_STS}
+      },
+      S_ACPI_IO_SMI_STS,
+      N_ACPI_IO_SMI_STS_ON_SLP_EN
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_ON_SLP_EN
+  }
+};
+
+/**
+  Get the Sleep type
+
+  @param[in] Record               No use
+  @param[out] Context             The context that includes SLP_TYP bits to be filled
+
+**/
+VOID
+EFIAPI
+SxGetContext (
+  IN  DATABASE_RECORD    *Record,
+  OUT PCH_SMM_CONTEXT    *Context
+  )
+{
+  UINT32  Pm1Cnt;
+
+  Pm1Cnt = IoRead32 ((UINTN) (mAcpiBaseAddr + R_ACPI_IO_PM1_CNT));
+
+  ///
+  /// By design, the context phase will always be ENTRY
+  ///
+  Context->Sx.Phase = SxEntry;
+
+  ///
+  /// Map the PM1_CNT register's SLP_TYP bits to the context type
+  ///
+  switch (Pm1Cnt & B_ACPI_IO_PM1_CNT_SLP_TYP) {
+    case V_ACPI_IO_PM1_CNT_S0:
+      Context->Sx.Type = SxS0;
+      break;
+
+    case V_ACPI_IO_PM1_CNT_S1:
+      Context->Sx.Type = SxS1;
+      break;
+
+    case V_ACPI_IO_PM1_CNT_S3:
+      Context->Sx.Type = SxS3;
+      break;
+
+    case V_ACPI_IO_PM1_CNT_S4:
+      Context->Sx.Type = SxS4;
+      break;
+
+    case V_ACPI_IO_PM1_CNT_S5:
+      Context->Sx.Type = SxS5;
+      break;
+
+    default:
+      ASSERT (FALSE);
+      break;
+  }
+}
+
+/**
+  Check whether sleep type of two contexts match
+
+  @param[in] Context1             Context 1 that includes sleep type 1
+  @param[in] Context2             Context 2 that includes sleep type 2
+
+  @retval FALSE                   Sleep types match
+  @retval TRUE                    Sleep types don't match
+**/
+BOOLEAN
+EFIAPI
+SxCmpContext (
+  IN PCH_SMM_CONTEXT     *Context1,
+  IN PCH_SMM_CONTEXT     *Context2
+  )
+{
+  return (BOOLEAN) (Context1->Sx.Type == Context2->Sx.Type);
+}
+
+/**
+  For each PCIE RP clear PME SCI status and disable SCI, then PCIEXP_WAKE_STS from PMC.
+  This prevents platform from waking more than one time due to a single PCIE wake event.
+  Normally it's up to OS to clear SCI statuses. But in a scenario where platform wakes
+  and goes to S5 instead of booting to OS, the SCI status would remain set and would trigger another wake.
+**/
+VOID
+ClearPcieSci (
+  VOID
+  )
+{
+  UINT32 MaxPorts;
+  UINT32 RpIndex;
+  UINT64 RpBase;
+
+  MaxPorts = GetPchMaxPciePortNum ();
+  for (RpIndex = 0; RpIndex < MaxPorts; RpIndex++) {
+    RpBase = PchPcieRpPciCfgBase (RpIndex);
+  if (PciSegmentRead16 (RpBase + PCI_VENDOR_ID_OFFSET) != 0xFFFF) {
+      PciSegmentAnd8 ((RpBase + R_PCH_PCIE_CFG_MPC + 3), (UINT8)~((UINT8)(B_PCH_PCIE_CFG_MPC_PMCE >> 24)));
+      PciSegmentWrite32 (RpBase + R_PCH_PCIE_CFG_SMSCS, B_PCH_PCIE_CFG_SMSCS_PMCS);
+    }
+  }
+  IoWrite16 (mAcpiBaseAddr + R_ACPI_IO_PM1_STS, B_ACPI_IO_PM1_STS_PCIEXP_WAKE_STS);
+}
+
+
+/**
+  When we get an SMI that indicates that we are transitioning to a sleep state,
+  we need to actually transition to that state.  We do this by disabling the
+  "SMI on sleep enable" feature, which generates an SMI when the operating system
+  tries to put the system to sleep, and then physically putting the system to sleep.
+
+
+**/
+VOID
+PchSmmSxGoToSleep (
+  VOID
+  )
+{
+  UINT32      Pm1Cnt;
+
+  ClearPcieSci ();
+
+  ///
+  /// Disable SMIs
+  ///
+  PchSmmClearSource (&mSxSourceDesc);
+  PchSmmDisableSource (&mSxSourceDesc);
+
+  ///
+  /// Get Power Management 1 Control Register Value
+  ///
+  Pm1Cnt = IoRead32 ((UINTN) (mAcpiBaseAddr + R_ACPI_IO_PM1_CNT));
+
+  ///
+  /// Record S3 suspend performance data
+  ///
+  if ((Pm1Cnt & B_ACPI_IO_PM1_CNT_SLP_TYP) == V_ACPI_IO_PM1_CNT_S3) {
+    ///
+    /// Report status code before goto S3 sleep
+    ///
+    REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PROGRESS_CODE_S3_SUSPEND_END);
+    mS3SusStart = FALSE;
+    ///
+    /// Write back cache into memory and invalidate cache before going to sleep.
+    ///
+    AsmWbinvd ();
+  }
+
+  ///
+  /// Now that SMIs are disabled, write to the SLP_EN bit again to trigger the sleep
+  ///
+  Pm1Cnt |= B_ACPI_IO_PM1_CNT_SLP_EN;
+
+  IoWrite32 ((UINTN) (mAcpiBaseAddr + R_ACPI_IO_PM1_CNT), Pm1Cnt);
+
+  ///
+  /// Should only proceed if wake event is generated.
+  ///
+  if ((Pm1Cnt & B_ACPI_IO_PM1_CNT_SLP_TYP) == V_ACPI_IO_PM1_CNT_S1) {
+    while (((IoRead16 ((UINTN) (mAcpiBaseAddr + R_ACPI_IO_PM1_STS))) & B_ACPI_IO_PM1_STS_WAK) == 0x0);
+  } else {
+    CpuDeadLoop ();
+  }
+  ///
+  /// The system just went to sleep. If the sleep state was S1, then code execution will resume
+  /// here when the system wakes up.
+  ///
+  Pm1Cnt = IoRead32 ((UINTN) (mAcpiBaseAddr + R_ACPI_IO_PM1_CNT));
+
+  if ((Pm1Cnt & B_ACPI_IO_PM1_CNT_SCI_EN) == 0) {
+    ///
+    /// An ACPI OS isn't present, clear the sleep information
+    ///
+    Pm1Cnt &= ~B_ACPI_IO_PM1_CNT_SLP_TYP;
+    Pm1Cnt |= V_ACPI_IO_PM1_CNT_S0;
+
+    IoWrite32 ((UINTN) (mAcpiBaseAddr + R_ACPI_IO_PM1_CNT), Pm1Cnt);
+  }
+
+  PchSmmClearSource (&mSxSourceDesc);
+  PchSmmEnableSource (&mSxSourceDesc);
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmUsb.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmUsb.c
new file mode 100644
index 0000000000..a0c67bd959
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchSmmUsb.c
@@ -0,0 +1,230 @@
+/** @file
+  File to contain all the hardware specific stuff for the Smm USB dispatch protocol.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "PchSmmHelpers.h"
+#include <Register/UsbRegs.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/PmcRegs.h>
+#include <Library/PchPciBdfLib.h>
+#include <PchBdfAssignment.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mUsb1Legacy = {
+  PCH_SMM_NO_FLAGS,
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_EN}
+      },
+      S_ACPI_IO_SMI_EN,
+      N_ACPI_IO_SMI_EN_LEGACY_USB
+    },
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_STS}
+      },
+      S_ACPI_IO_SMI_STS,
+      N_ACPI_IO_SMI_STS_LEGACY_USB
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_LEGACY_USB
+  }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_SMM_SOURCE_DESC mUsb3Legacy = {
+  PCH_SMM_NO_FLAGS,
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_EN}
+      },
+      S_ACPI_IO_SMI_EN,
+      N_ACPI_IO_SMI_EN_LEGACY_USB3
+    },
+    NULL_BIT_DESC_INITIALIZER
+  },
+  {
+    {
+      {
+        ACPI_ADDR_TYPE,
+        {R_ACPI_IO_SMI_STS}
+      },
+      S_ACPI_IO_SMI_STS,
+      N_ACPI_IO_SMI_STS_LEGACY_USB3
+    }
+  },
+  {
+    {
+      ACPI_ADDR_TYPE,
+      {R_ACPI_IO_SMI_STS}
+    },
+    S_ACPI_IO_SMI_STS,
+    N_ACPI_IO_SMI_STS_LEGACY_USB3
+  }
+};
+
+typedef enum {
+  PchUsbControllerLpc0    = 0,
+  PchUsbControllerXhci,
+  PchUsbControllerTypeMax
+} PCH_USB_CONTROLLER_TYPE;
+
+typedef struct {
+  UINT8                   Function;
+  UINT8                   Device;
+  PCH_USB_CONTROLLER_TYPE UsbConType;
+} USB_CONTROLLER;
+
+GLOBAL_REMOVE_IF_UNREFERENCED USB_CONTROLLER  mUsbControllersMap[] = {
+  {
+    PCI_FUNCTION_NUMBER_PCH_LPC,
+    PCI_DEVICE_NUMBER_PCH_LPC,
+    PchUsbControllerLpc0
+  },
+  {
+    PCI_FUNCTION_NUMBER_PCH_XHCI,
+    PCI_DEVICE_NUMBER_PCH_XHCI,
+    PchUsbControllerXhci
+  }
+};
+
+/**
+  Find the handle that best matches the input Device Path and return the USB controller type
+
+  @param[in] DevicePath           Pointer to the device Path table
+  @param[out] Controller          Returned with the USB controller type of the input device path
+
+  @retval EFI_SUCCESS             Find the handle that best matches the input Device Path
+  @exception EFI_UNSUPPORTED      Invalid device Path table or can't find any match USB device path
+                                  PCH_USB_CONTROLLER_TYPE The USB controller type of the input
+                                  device path
+**/
+EFI_STATUS
+DevicePathToSupportedController (
+  IN  EFI_DEVICE_PATH_PROTOCOL   *DevicePath,
+  OUT PCH_USB_CONTROLLER_TYPE    *Controller
+  )
+{
+  EFI_STATUS                Status;
+  EFI_HANDLE                DeviceHandle;
+  ACPI_HID_DEVICE_PATH      *AcpiNode;
+  PCI_DEVICE_PATH           *PciNode;
+  EFI_DEVICE_PATH_PROTOCOL  *RemaingDevicePath;
+  UINT8                     UsbIndex;
+  ///
+  /// Find the handle that best matches the Device Path. If it is only a
+  /// partial match the remaining part of the device path is returned in
+  /// RemainingDevicePath.
+  ///
+  RemaingDevicePath = DevicePath;
+  Status = gBS->LocateDevicePath (
+                  &gEfiPciRootBridgeIoProtocolGuid,
+                  &DevicePath,
+                  &DeviceHandle
+                  );
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  DevicePath = RemaingDevicePath;
+
+  ///
+  /// Get first node: Acpi Node
+  ///
+  AcpiNode = (ACPI_HID_DEVICE_PATH *) RemaingDevicePath;
+
+  if (AcpiNode->Header.Type != ACPI_DEVICE_PATH ||
+      AcpiNode->Header.SubType != ACPI_DP ||
+      DevicePathNodeLength (&AcpiNode->Header) != sizeof (ACPI_HID_DEVICE_PATH) ||
+      AcpiNode->HID != EISA_PNP_ID (0x0A03) ||
+      AcpiNode->UID != 0
+      ) {
+    return EFI_UNSUPPORTED;
+  } else {
+    ///
+    /// Get the next node: Pci Node
+    ///
+    RemaingDevicePath = NextDevicePathNode (RemaingDevicePath);
+    PciNode           = (PCI_DEVICE_PATH *) RemaingDevicePath;
+    if (PciNode->Header.Type != HARDWARE_DEVICE_PATH ||
+        PciNode->Header.SubType != HW_PCI_DP ||
+        DevicePathNodeLength (&PciNode->Header) != sizeof (PCI_DEVICE_PATH)
+        ) {
+      return EFI_UNSUPPORTED;
+    }
+
+    for (UsbIndex = 0; UsbIndex < sizeof (mUsbControllersMap) / sizeof (USB_CONTROLLER); UsbIndex++) {
+      if ((PciNode->Device == mUsbControllersMap[UsbIndex].Device) &&
+          (PciNode->Function == mUsbControllersMap[UsbIndex].Function)) {
+        *Controller = mUsbControllersMap[UsbIndex].UsbConType;
+        return EFI_SUCCESS;
+      }
+    }
+
+    return EFI_UNSUPPORTED;
+  }
+}
+
+/**
+  Maps a USB context to a source description.
+
+  @param[in] Context              The context we need to map.  Type must be USB.
+  @param[in] SrcDesc              The source description that corresponds to the given context.
+
+**/
+VOID
+MapUsbToSrcDesc (
+  IN  PCH_SMM_CONTEXT         *Context,
+  OUT PCH_SMM_SOURCE_DESC     *SrcDesc
+  )
+{
+  PCH_USB_CONTROLLER_TYPE Controller;
+  EFI_STATUS              Status;
+
+  Status = DevicePathToSupportedController (Context->Usb.Device, &Controller);
+  ///
+  /// Either the device path passed in by the child is incorrect or
+  /// the ones stored here internally are incorrect.
+  ///
+  ASSERT_EFI_ERROR (Status);
+
+  switch (Context->Usb.Type) {
+    case UsbLegacy:
+      switch (Controller) {
+        case PchUsbControllerLpc0:
+          CopyMem ((VOID *) SrcDesc, (VOID *) (&mUsb1Legacy), sizeof (PCH_SMM_SOURCE_DESC));
+          break;
+
+        case PchUsbControllerXhci:
+          CopyMem ((VOID *) SrcDesc, (VOID *) (&mUsb3Legacy), sizeof (PCH_SMM_SOURCE_DESC));
+          break;
+
+        default:
+          ASSERT (FALSE);
+          break;
+      }
+      break;
+
+    case UsbWake:
+      ASSERT (FALSE);
+      break;
+
+    default:
+      ASSERT (FALSE);
+      break;
+  }
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.c
new file mode 100644
index 0000000000..a0b7e37d46
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.c
@@ -0,0 +1,778 @@
+/** @file
+  This driver is responsible for the registration of child drivers
+  and the abstraction of the PCH SMI sources.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "PchSmmHelpers.h"
+#include <Register/PchRegs.h>
+#include <Register/PmcRegs.h>
+
+//
+// Help handle porting bit shifts to IA-64.
+//
+#define BIT_ZERO  0x00000001
+
+/**
+  Publish SMI Dispatch protocols.
+
+
+**/
+VOID
+PchSmmPublishDispatchProtocols (
+  VOID
+  )
+{
+  EFI_STATUS Status = EFI_SUCCESS;
+  UINTN      Index;
+  //
+  // Install protocol interfaces.
+  //
+  for (Index = 0; Index < PCH_SMM_PROTOCOL_TYPE_MAX; Index++) {
+    Status = gSmst->SmmInstallProtocolInterface (
+                      &mPrivateData.InstallMultProtHandle,
+                      mPrivateData.Protocols[Index].Guid,
+                      EFI_NATIVE_INTERFACE,
+                      &mPrivateData.Protocols[Index].Protocols.Generic
+                      );
+  }
+  ASSERT_EFI_ERROR (Status);
+}
+
+/**
+  Initialize bits that aren't necessarily related to an SMI source.
+
+
+  @retval EFI_SUCCESS             SMI source initialization completed.
+  @retval Asserts                 Global Smi Bit is not enabled successfully.
+**/
+EFI_STATUS
+PchSmmInitHardware (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+
+  //
+  // Clear all SMIs
+  //
+  PchSmmClearSmi ();
+
+  Status = PchSmmEnableGlobalSmiBit ();
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Be *really* sure to clear all SMIs
+  //
+  PchSmmClearSmi ();
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Enables the PCH to generate SMIs. Note that no SMIs will be generated
+  if no SMI sources are enabled. Conversely, no enabled SMI source will
+  generate SMIs if SMIs are not globally enabled. This is the main
+  switchbox for SMI generation.
+
+
+  @retval EFI_SUCCESS             Enable Global Smi Bit completed
+**/
+EFI_STATUS
+PchSmmEnableGlobalSmiBit (
+  VOID
+  )
+{
+  UINT32  SmiEn;
+
+  SmiEn = IoRead32 ((UINTN) (mAcpiBaseAddr + R_ACPI_IO_SMI_EN));
+
+  //
+  // Set the "global smi enable" bit
+  //
+  SmiEn |= B_ACPI_IO_SMI_EN_GBL_SMI;
+
+  IoWrite32 ((UINTN) (mAcpiBaseAddr + R_ACPI_IO_SMI_EN), SmiEn);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Clears the SMI after all SMI source have been processed.
+  Note that this function will not work correctly (as it is
+  written) unless all SMI sources have been processed.
+  A revision of this function could manually clear all SMI
+  status bits to guarantee success.
+
+
+  @retval EFI_SUCCESS             Clears the SMIs completed
+  @retval Asserts                 EOS was not set to a 1
+**/
+EFI_STATUS
+PchSmmClearSmi (
+  VOID
+  )
+{
+  BOOLEAN     EosSet;
+  BOOLEAN     SciEn;
+  UINT32      Pm1Cnt;
+  UINT16      Pm1Sts;
+  UINT32      Gpe0Sts;
+  UINT32      SmiSts;
+  UINT16      DevActSts;
+  UINT16      Tco1Sts;
+
+  Gpe0Sts      = 0;
+  //
+  // Determine whether an ACPI OS is present (via the SCI_EN bit)
+  //
+  Pm1Cnt = IoRead32 ((UINTN) (mAcpiBaseAddr + R_ACPI_IO_PM1_CNT));
+  SciEn  = (BOOLEAN) ((Pm1Cnt & B_ACPI_IO_PM1_CNT_SCI_EN) == B_ACPI_IO_PM1_CNT_SCI_EN);
+  if (!SciEn) {
+    //
+    // Clear any SMIs that double as SCIs (when SCI_EN==0)
+    //
+    Pm1Sts   = IoRead16 ((UINTN) (mAcpiBaseAddr + R_ACPI_IO_PM1_STS));
+    Gpe0Sts  = IoRead32 ((UINTN) (mAcpiBaseAddr + R_ACPI_IO_GPE0_STS_127_96));
+
+    Pm1Sts |=
+    (
+      B_ACPI_IO_PM1_STS_WAK |
+      B_ACPI_IO_PM1_STS_PRBTNOR |
+      B_ACPI_IO_PM1_STS_RTC |
+      B_ACPI_IO_PM1_STS_PWRBTN |
+      B_ACPI_IO_PM1_STS_GBL |
+      B_ACPI_IO_PM1_STS_TMROF
+      );
+
+    Gpe0Sts |=
+    (
+      B_ACPI_IO_GPE0_STS_127_96_WADT |
+      B_ACPI_IO_GPE0_STS_127_96_USB_CON_DSX_STS |
+      B_ACPI_IO_GPE0_STS_127_96_LAN_WAKE |
+      B_ACPI_IO_GPE0_STS_127_96_PME_B0 |
+      B_ACPI_IO_GPE0_STS_127_96_PME |
+      B_ACPI_IO_GPE0_STS_127_96_BATLOW |
+      B_ACPI_IO_GPE0_STS_127_96_RI |
+      B_ACPI_IO_GPE0_STS_127_96_SWGPE
+      );
+
+    IoWrite16 ((UINTN) (mAcpiBaseAddr + R_ACPI_IO_PM1_STS), (UINT16) Pm1Sts);
+    IoWrite32 ((UINTN) (mAcpiBaseAddr + R_ACPI_IO_GPE0_STS_127_96), (UINT32) Gpe0Sts);
+  }
+  //
+  // Clear all SMIs that are unaffected by SCI_EN
+  //
+  SmiSts        = IoRead32 ((UINTN) (mAcpiBaseAddr + R_ACPI_IO_SMI_STS));
+  DevActSts     = IoRead16 ((UINTN) (mAcpiBaseAddr + R_ACPI_IO_DEVACT_STS));
+  Tco1Sts       = IoRead16 ((UINTN) (mTcoBaseAddr + R_TCO_IO_TCO1_STS));
+
+  SmiSts |=
+  (
+    B_ACPI_IO_SMI_STS_SMBUS |
+    B_ACPI_IO_SMI_STS_PERIODIC |
+    B_ACPI_IO_SMI_STS_TCO |
+    B_ACPI_IO_SMI_STS_MCSMI |
+    B_ACPI_IO_SMI_STS_SWSMI_TMR |
+    B_ACPI_IO_SMI_STS_APM |
+    B_ACPI_IO_SMI_STS_ON_SLP_EN |
+    B_ACPI_IO_SMI_STS_BIOS
+    );
+  DevActSts |=
+  (
+    B_ACPI_IO_DEVACT_STS_KBC |
+    B_ACPI_IO_DEVACT_STS_PIRQDH |
+    B_ACPI_IO_DEVACT_STS_PIRQCG |
+    B_ACPI_IO_DEVACT_STS_PIRQBF |
+    B_ACPI_IO_DEVACT_STS_PIRQAE
+    );
+  Tco1Sts |=
+  (
+    B_TCO_IO_TCO1_STS_DMISERR |
+    B_TCO_IO_TCO1_STS_DMISMI |
+    B_TCO_IO_TCO1_STS_DMISCI |
+    B_TCO_IO_TCO1_STS_BIOSWR |
+    B_TCO_IO_TCO1_STS_NEWCENTURY |
+    B_TCO_IO_TCO1_STS_TIMEOUT |
+    B_TCO_IO_TCO1_STS_TCO_INT |
+    B_TCO_IO_TCO1_STS_SW_TCO_SMI
+    );
+
+  GpioClearAllGpiSmiSts ();
+
+  IoWrite16 ((UINTN) (mTcoBaseAddr + R_TCO_IO_TCO1_STS), Tco1Sts);
+
+  //
+  // We do not want to write 1 to clear INTRD_DET bit.
+  //
+  IoWrite16 ((UINTN) (mTcoBaseAddr + R_TCO_IO_TCO2_STS), (UINT16) ~B_TCO_IO_TCO2_STS_INTRD_DET);
+
+  IoWrite32 ((UINTN) (mAcpiBaseAddr + R_ACPI_IO_SMI_STS), SmiSts);
+
+  IoWrite16 ((UINTN) (mAcpiBaseAddr + R_ACPI_IO_DEVACT_STS), DevActSts);
+
+  //
+  // Try to clear the EOS bit. ASSERT on an error
+  //
+  EosSet = PchSmmSetAndCheckEos ();
+  ASSERT (EosSet);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Set the SMI EOS bit after all SMI source have been processed.
+
+
+  @retval FALSE                   EOS was not set to a 1; this is an error
+  @retval TRUE                    EOS was correctly set to a 1
+**/
+BOOLEAN
+PchSmmSetAndCheckEos (
+  VOID
+  )
+{
+  UINT32  SmiEn;
+
+  SmiEn = IoRead32 ((UINTN) (mAcpiBaseAddr + R_ACPI_IO_SMI_EN));
+
+  //
+  // Reset the PCH to generate subsequent SMIs
+  //
+  SmiEn |= B_ACPI_IO_SMI_EN_EOS;
+
+  IoWrite32 ((UINTN) (mAcpiBaseAddr + R_ACPI_IO_SMI_EN), SmiEn);
+
+  //
+  // Double check that the assert worked
+  //
+  SmiEn = IoRead32 ((UINTN) (mAcpiBaseAddr + R_ACPI_IO_SMI_EN));
+
+  //
+  // Return TRUE if EOS is set correctly
+  //
+  if ((SmiEn & B_ACPI_IO_SMI_EN_EOS) == 0) {
+    //
+    // EOS was not set to a 1; this is an error
+    //
+    return FALSE;
+  } else {
+    //
+    // EOS was correctly set to a 1
+    //
+    return TRUE;
+  }
+}
+
+/**
+  Determine whether an ACPI OS is present (via the SCI_EN bit)
+
+
+  @retval TRUE                    ACPI OS is present
+  @retval FALSE                   ACPI OS is not present
+**/
+BOOLEAN
+PchSmmGetSciEn (
+  VOID
+  )
+{
+  BOOLEAN SciEn;
+  UINT32  Pm1Cnt;
+
+  //
+  // Determine whether an ACPI OS is present (via the SCI_EN bit)
+  //
+  Pm1Cnt  = IoRead32 ((UINTN) (mAcpiBaseAddr + R_ACPI_IO_PM1_CNT));
+  SciEn   = (BOOLEAN) ((Pm1Cnt & B_ACPI_IO_PM1_CNT_SCI_EN) == B_ACPI_IO_PM1_CNT_SCI_EN);
+
+  return SciEn;
+}
+
+/**
+  Read a specifying bit with the register
+  These may or may not need to change w/ the PCH version; they're highly IA-32 dependent, though.
+
+  @param[in] BitDesc              The struct that includes register address, size in byte and bit number
+
+  @retval TRUE                    The bit is enabled
+  @retval FALSE                   The bit is disabled
+**/
+BOOLEAN
+ReadBitDesc (
+  CONST PCH_SMM_BIT_DESC  *BitDesc
+  )
+{
+  EFI_STATUS  Status;
+  UINT64      Register;
+  UINT32      PciBus;
+  UINT32      PciDev;
+  UINT32      PciFun;
+  UINT32      PciReg;
+  UINTN       RegSize;
+  BOOLEAN     BitWasOne;
+  UINTN       ShiftCount;
+  UINTN       RegisterOffset;
+  UINT32      BaseAddr;
+  UINT64      PciBaseAddress;
+
+  ASSERT (BitDesc != NULL);
+  ASSERT (!IS_BIT_DESC_NULL (*BitDesc));
+
+  RegSize     = 0;
+  Register    = 0;
+  ShiftCount  = 0;
+  BitWasOne   = FALSE;
+
+  switch (BitDesc->Reg.Type) {
+
+    case ACPI_ADDR_TYPE:
+    case TCO_ADDR_TYPE:
+      if (BitDesc->Reg.Type == ACPI_ADDR_TYPE) {
+        RegisterOffset  = BitDesc->Reg.Data.acpi;
+        BaseAddr        = mAcpiBaseAddr;
+      } else {
+        RegisterOffset  = BitDesc->Reg.Data.tco;
+        BaseAddr        = mTcoBaseAddr;
+      }
+      switch (BitDesc->SizeInBytes) {
+
+        case 0:
+          //
+          // Chances are that this field didn't get initialized.
+          // Check your assignments to bit descriptions.
+          //
+          ASSERT (FALSE);
+          break;
+
+        case 1:
+          RegSize = SMM_IO_UINT8;
+          break;
+
+        case 2:
+          RegSize = SMM_IO_UINT16;
+          break;
+
+        case 4:
+          RegSize = SMM_IO_UINT32;
+          break;
+
+        case 8:
+          RegSize = SMM_IO_UINT64;
+          break;
+
+        default:
+          //
+          // Unsupported or invalid register size
+          //
+          ASSERT (FALSE);
+          break;
+      }
+      //
+      // Double check that we correctly read in the acpi base address
+      //
+      ASSERT ((BaseAddr != 0x0) && ((BaseAddr & 0x1) != 0x1));
+
+      ShiftCount      = BitDesc->Bit;
+      //
+      // As current CPU Smm Io can only support at most
+      // 32-bit read/write,if Operation is 64 bit,
+      // we do a 32 bit operation according to BitDesc->Bit
+      //
+      if (RegSize == SMM_IO_UINT64) {
+        RegSize = SMM_IO_UINT32;
+        //
+        // If the operation is for high 32 bits
+        //
+        if (BitDesc->Bit >= 32) {
+          RegisterOffset += 4;
+          ShiftCount -= 32;
+        }
+      }
+
+      Status = gSmst->SmmIo.Io.Read (
+                                 &gSmst->SmmIo,
+                                 RegSize,
+                                 BaseAddr + RegisterOffset,
+                                 1,
+                                 &Register
+                                 );
+      ASSERT_EFI_ERROR (Status);
+
+      if ((Register & (LShiftU64 (BIT_ZERO, ShiftCount))) != 0) {
+        BitWasOne = TRUE;
+      } else {
+        BitWasOne = FALSE;
+      }
+      break;
+
+    case GPIO_ADDR_TYPE:
+    case MEMORY_MAPPED_IO_ADDRESS_TYPE:
+      //
+      // Read the register, and it with the bit to read
+      //
+      switch (BitDesc->SizeInBytes) {
+        case 1:
+          Register = (UINT64) MmioRead8 ((UINTN) BitDesc->Reg.Data.Mmio);
+          break;
+
+        case 2:
+          Register = (UINT64) MmioRead16 ((UINTN) BitDesc->Reg.Data.Mmio);
+          break;
+
+        case 4:
+          Register = (UINT64) MmioRead32 ((UINTN) BitDesc->Reg.Data.Mmio);
+          break;
+
+        case 8:
+          Register                      = (UINT64) MmioRead32 ((UINTN) BitDesc->Reg.Data.Mmio);
+          *((UINT32 *) (&Register) + 1) = MmioRead32 ((UINTN) BitDesc->Reg.Data.Mmio + 4);
+          break;
+
+        default:
+          //
+          // Unsupported or invalid register size
+          //
+          ASSERT (FALSE);
+          break;
+      }
+
+      Register = Register & (LShiftU64 (BIT0, BitDesc->Bit));
+      if (Register) {
+        BitWasOne = TRUE;
+      } else {
+        BitWasOne = FALSE;
+      }
+      break;
+
+    case PCIE_ADDR_TYPE:
+      PciBus  = BitDesc->Reg.Data.pcie.Fields.Bus;
+      PciDev  = BitDesc->Reg.Data.pcie.Fields.Dev;
+      PciFun  = BitDesc->Reg.Data.pcie.Fields.Fnc;
+      PciReg  = BitDesc->Reg.Data.pcie.Fields.Reg;
+      PciBaseAddress = PCI_SEGMENT_LIB_ADDRESS (DEFAULT_PCI_SEGMENT_NUMBER_PCH, PciBus, PciDev, PciFun, 0);
+      switch (BitDesc->SizeInBytes) {
+
+        case 0:
+          //
+          // Chances are that this field didn't get initialized.
+          // Check your assignments to bit descriptions.
+          //
+          ASSERT (FALSE);
+          break;
+
+        case 1:
+          Register = (UINT64) PciSegmentRead8 (PciBaseAddress + PciReg);
+          break;
+
+        case 2:
+          Register = (UINT64) PciSegmentRead16 (PciBaseAddress + PciReg);
+          break;
+
+        case 4:
+          Register = (UINT64) PciSegmentRead32 (PciBaseAddress + PciReg);
+          break;
+
+        default:
+          //
+          // Unsupported or invalid register size
+          //
+          ASSERT (FALSE);
+          break;
+      }
+
+      if ((Register & (LShiftU64 (BIT_ZERO, BitDesc->Bit))) != 0) {
+        BitWasOne = TRUE;
+      } else {
+        BitWasOne = FALSE;
+      }
+      break;
+
+    case PCR_ADDR_TYPE:
+      //
+      // Read the register, and it with the bit to read
+      //
+      switch (BitDesc->SizeInBytes) {
+        case 1:
+          Register = PchPcrRead8  (BitDesc->Reg.Data.Pcr.Fields.Pid, BitDesc->Reg.Data.Pcr.Fields.Offset);
+          break;
+
+        case 2:
+          Register = PchPcrRead16 (BitDesc->Reg.Data.Pcr.Fields.Pid, BitDesc->Reg.Data.Pcr.Fields.Offset);
+          break;
+
+        case 4:
+          Register = PchPcrRead32 (BitDesc->Reg.Data.Pcr.Fields.Pid, BitDesc->Reg.Data.Pcr.Fields.Offset);
+          break;
+
+        default:
+          //
+          // Unsupported or invalid register size
+          //
+          ASSERT (FALSE);
+          break;
+      }
+
+      Register = Register & (LShiftU64 (BIT0, BitDesc->Bit));
+      if (Register) {
+        BitWasOne = TRUE;
+      } else {
+        BitWasOne = FALSE;
+      }
+      break;
+
+    default:
+      //
+      // This address type is not yet implemented
+      //
+      ASSERT (FALSE);
+      break;
+  }
+
+  return BitWasOne;
+}
+
+/**
+  Write a specifying bit with the register
+
+  @param[in] BitDesc              The struct that includes register address, size in byte and bit number
+  @param[in] ValueToWrite         The value to be wrote
+  @param[in] WriteClear           If the rest bits of the register is write clear
+
+**/
+VOID
+WriteBitDesc (
+  CONST PCH_SMM_BIT_DESC  *BitDesc,
+  CONST BOOLEAN           ValueToWrite,
+  CONST BOOLEAN           WriteClear
+  )
+{
+  EFI_STATUS  Status;
+  UINT64      Register;
+  UINT64      AndVal;
+  UINT64      OrVal;
+  UINT32      RegSize;
+  UINT32      PciBus;
+  UINT32      PciDev;
+  UINT32      PciFun;
+  UINT32      PciReg;
+  UINTN       RegisterOffset;
+  UINT32      BaseAddr;
+  UINT64      PciBaseAddress;
+
+  ASSERT (BitDesc != NULL);
+  ASSERT (!IS_BIT_DESC_NULL (*BitDesc));
+
+  RegSize   = 0;
+  Register  = 0;
+
+  if (WriteClear) {
+    AndVal = LShiftU64 (BIT_ZERO, BitDesc->Bit);
+  } else {
+    AndVal = ~(LShiftU64 (BIT_ZERO, BitDesc->Bit));
+  }
+
+  OrVal = (LShiftU64 ((UINT32) ValueToWrite, BitDesc->Bit));
+
+  switch (BitDesc->Reg.Type) {
+
+    case ACPI_ADDR_TYPE:
+    case TCO_ADDR_TYPE:
+      if (BitDesc->Reg.Type == ACPI_ADDR_TYPE) {
+        RegisterOffset  = BitDesc->Reg.Data.acpi;
+        BaseAddr        = mAcpiBaseAddr;
+      } else {
+        RegisterOffset  = BitDesc->Reg.Data.tco;
+        BaseAddr        = mTcoBaseAddr;
+      }
+
+      switch (BitDesc->SizeInBytes) {
+
+        case 0:
+          //
+          // Chances are that this field didn't get initialized.
+          // Check your assignments to bit descriptions.
+          //
+          ASSERT (FALSE);
+          break;
+
+        case 1:
+          RegSize = SMM_IO_UINT8;
+          break;
+
+        case 2:
+          RegSize = SMM_IO_UINT16;
+          break;
+
+        case 4:
+          RegSize = SMM_IO_UINT32;
+          break;
+
+        case 8:
+          RegSize = SMM_IO_UINT64;
+          break;
+
+        default:
+          //
+          // Unsupported or invalid register size
+          //
+          ASSERT (FALSE);
+          break;
+      }
+      //
+      // Double check that we correctly read in the acpi base address
+      //
+      ASSERT ((BaseAddr != 0x0) && ((BaseAddr & 0x1) != 0x1));
+
+      //
+      // As current CPU Smm Io can only support at most
+      // 32-bit read/write,if Operation is 64 bit,
+      // we do a 32 bit operation according to BitDesc->Bit
+      //
+      if (RegSize == SMM_IO_UINT64) {
+        RegSize = SMM_IO_UINT32;
+        //
+        // If the operation is for high 32 bits
+        //
+        if (BitDesc->Bit >= 32) {
+          RegisterOffset += 4;
+
+          if (WriteClear) {
+            AndVal = LShiftU64 (BIT_ZERO, BitDesc->Bit - 32);
+          } else {
+            AndVal = ~(LShiftU64 (BIT_ZERO, BitDesc->Bit - 32));
+          }
+
+          OrVal = LShiftU64 ((UINT32) ValueToWrite, BitDesc->Bit - 32);
+        }
+      }
+
+      Status = gSmst->SmmIo.Io.Read (
+                                 &gSmst->SmmIo,
+                                 RegSize,
+                                 BaseAddr + RegisterOffset,
+                                 1,
+                                 &Register
+                                 );
+      ASSERT_EFI_ERROR (Status);
+
+      Register &= AndVal;
+      Register |= OrVal;
+
+      Status = gSmst->SmmIo.Io.Write (
+                                 &gSmst->SmmIo,
+                                 RegSize,
+                                 BaseAddr + RegisterOffset,
+                                 1,
+                                 &Register
+                                 );
+      ASSERT_EFI_ERROR (Status);
+      break;
+
+    case GPIO_ADDR_TYPE:
+    case MEMORY_MAPPED_IO_ADDRESS_TYPE:
+      //
+      // Read the register, or it with the bit to set, then write it back.
+      //
+      switch (BitDesc->SizeInBytes) {
+        case 1:
+          MmioAndThenOr8  ((UINTN) BitDesc->Reg.Data.Mmio, (UINT8)  AndVal, (UINT8)  OrVal);
+          break;
+
+        case 2:
+          MmioAndThenOr16 ((UINTN) BitDesc->Reg.Data.Mmio, (UINT16) AndVal, (UINT16) OrVal);
+          break;
+
+        case 4:
+          MmioAndThenOr32 ((UINTN) BitDesc->Reg.Data.Mmio, (UINT32) AndVal, (UINT32) OrVal);
+          break;
+
+        case 8:
+          Register                      = (UINT64) MmioRead32 ((UINTN) BitDesc->Reg.Data.Mmio);
+          *((UINT32 *) (&Register) + 1) = MmioRead32 ((UINTN) BitDesc->Reg.Data.Mmio + 4);
+          Register &= AndVal;
+          Register |= OrVal;
+          MmioWrite32 ((UINTN) BitDesc->Reg.Data.Mmio, (UINT32) Register);
+          MmioWrite32 ((UINTN) BitDesc->Reg.Data.Mmio + 4, *((UINT32 *) (&Register) + 1));
+          break;
+
+        default:
+          //
+          // Unsupported or invalid register size
+          //
+          ASSERT (FALSE);
+          break;
+      }
+      break;
+
+    case PCIE_ADDR_TYPE:
+      PciBus  = BitDesc->Reg.Data.pcie.Fields.Bus;
+      PciDev  = BitDesc->Reg.Data.pcie.Fields.Dev;
+      PciFun  = BitDesc->Reg.Data.pcie.Fields.Fnc;
+      PciReg  = BitDesc->Reg.Data.pcie.Fields.Reg;
+      PciBaseAddress = PCI_SEGMENT_LIB_ADDRESS (DEFAULT_PCI_SEGMENT_NUMBER_PCH, PciBus, PciDev, PciFun, 0);
+      switch (BitDesc->SizeInBytes) {
+
+        case 0:
+          //
+          // Chances are that this field didn't get initialized -- check your assignments
+          // to bit descriptions.
+          //
+          ASSERT (FALSE);
+          break;
+
+        case 1:
+          PciSegmentAndThenOr8 (PciBaseAddress + PciReg, (UINT8) AndVal, (UINT8) OrVal);
+          break;
+
+        case 2:
+          PciSegmentAndThenOr16 (PciBaseAddress + PciReg, (UINT16) AndVal, (UINT16) OrVal);
+          break;
+
+        case 4:
+          PciSegmentAndThenOr32 (PciBaseAddress + PciReg, (UINT32) AndVal, (UINT32) OrVal);
+          break;
+
+        default:
+          //
+          // Unsupported or invalid register size
+          //
+          ASSERT (FALSE);
+          break;
+      }
+      break;
+
+    case PCR_ADDR_TYPE:
+      //
+      // Read the register, or it with the bit to set, then write it back.
+      //
+      switch (BitDesc->SizeInBytes) {
+        case 1:
+          PchPcrAndThenOr8  ((PCH_SBI_PID) BitDesc->Reg.Data.Pcr.Fields.Pid, (UINT16) BitDesc->Reg.Data.Pcr.Fields.Offset, (UINT8)  AndVal, (UINT8)  OrVal);
+          break;
+
+        case 2:
+          PchPcrAndThenOr16 ((PCH_SBI_PID) BitDesc->Reg.Data.Pcr.Fields.Pid, (UINT16) BitDesc->Reg.Data.Pcr.Fields.Offset, (UINT16) AndVal, (UINT16) OrVal);
+          break;
+
+        case 4:
+          PchPcrAndThenOr32 ((PCH_SBI_PID) BitDesc->Reg.Data.Pcr.Fields.Pid, (UINT16) BitDesc->Reg.Data.Pcr.Fields.Offset, (UINT32) AndVal, (UINT32) OrVal);
+          break;
+
+        default:
+          //
+          // Unsupported or invalid register size
+          //
+          ASSERT (FALSE);
+          break;
+      }
+      break;
+
+    default:
+      //
+      // This address type is not yet implemented
+      //
+      ASSERT (FALSE);
+      break;
+  }
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.h
new file mode 100644
index 0000000000..6dd6f2027d
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/PchSmiDispatcher/Smm/PchxSmmHelpers.h
@@ -0,0 +1,107 @@
+/** @file
+  This driver is responsible for the registration of child drivers
+  and the abstraction of the PCH SMI sources.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCHX_SMM_HELPERS_H_
+#define _PCHX_SMM_HELPERS_H_
+
+#include "PchSmm.h"
+
+/**
+  Initialize bits that aren't necessarily related to an SMI source.
+
+
+  @retval EFI_SUCCESS             SMI source initialization completed.
+  @retval Asserts                 Global Smi Bit is not enabled successfully.
+**/
+EFI_STATUS
+PchSmmInitHardware (
+  VOID
+  );
+
+/**
+  Enables the PCH to generate SMIs. Note that no SMIs will be generated
+  if no SMI sources are enabled. Conversely, no enabled SMI source will
+  generate SMIs if SMIs are not globally enabled. This is the main
+  switchbox for SMI generation.
+
+
+  @retval EFI_SUCCESS             Enable Global Smi Bit completed
+**/
+EFI_STATUS
+PchSmmEnableGlobalSmiBit (
+  VOID
+  );
+
+/**
+  Clears the SMI after all SMI source have been processed.
+  Note that this function will not work correctly (as it is
+  written) unless all SMI sources have been processed.
+  A revision of this function could manually clear all SMI
+  status bits to guarantee success.
+
+
+  @retval EFI_SUCCESS             Clears the SMIs completed
+  @retval Asserts                 EOS was not set to a 1
+**/
+EFI_STATUS
+PchSmmClearSmi (
+  VOID
+  );
+
+/**
+  Set the SMI EOS bit after all SMI source have been processed.
+
+
+  @retval FALSE                   EOS was not set to a 1; this is an error
+  @retval TRUE                    EOS was correctly set to a 1
+**/
+BOOLEAN
+PchSmmSetAndCheckEos (
+  VOID
+  );
+
+/**
+  Determine whether an ACPI OS is present (via the SCI_EN bit)
+
+
+  @retval TRUE                    ACPI OS is present
+  @retval FALSE                   ACPI OS is not present
+**/
+BOOLEAN
+PchSmmGetSciEn (
+  VOID
+  );
+
+/**
+  Read a specifying bit with the register
+
+  @param[in] BitDesc              The struct that includes register address, size in byte and bit number
+
+  @retval TRUE                    The bit is enabled
+  @retval FALSE                   The bit is disabled
+**/
+BOOLEAN
+ReadBitDesc (
+  CONST PCH_SMM_BIT_DESC *BitDesc
+  );
+
+/**
+  Write a specifying bit with the register
+
+  @param[in] BitDesc              The struct that includes register address, size in byte and bit number
+  @param[in] ValueToWrite         The value to be wrote
+  @param[in] WriteClear           If the rest bits of the register is write clear
+
+**/
+VOID
+WriteBitDesc (
+  CONST PCH_SMM_BIT_DESC  *BitDesc,
+  CONST BOOLEAN           ValueToWrite,
+  CONST BOOLEAN           WriteClear
+  );
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControl.inf b/Silicon/Intel/TigerlakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControl.inf
new file mode 100644
index 0000000000..a142cfa95a
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControl.inf
@@ -0,0 +1,54 @@
+## @file
+# Component description file for SmmControl module
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = SmmControl
+FILE_GUID = A0BAD9F7-AB78-491b-B583-C52B7F84B9E0
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_RUNTIME_DRIVER
+ENTRY_POINT = SmmControlDriverEntryInit
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+
+
+[LibraryClasses]
+IoLib
+UefiDriverEntryPoint
+DebugLib
+UefiBootServicesTableLib
+UefiRuntimeServicesTableLib
+PmcLib
+GpioLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+SmmControlDriver.h
+SmmControlDriver.c
+
+
+[Protocols]
+gEfiSmmControl2ProtocolGuid ## PRODUCES
+
+
+[Guids]
+gEfiEventVirtualAddressChangeGuid
+
+
+[Depex]
+TRUE
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.c b/Silicon/Intel/TigerlakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.c
new file mode 100644
index 0000000000..5822f42165
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.c
@@ -0,0 +1,394 @@
+/** @file
+  This is the driver that publishes the SMM Control Protocol.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Guid/EventGroup.h>
+#include <Library/PmcLib.h>
+#include <Library/GpioLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/SpiRegs.h>
+#include <Register/PmcRegs.h>
+#include "SmmControlDriver.h"
+
+STATIC SMM_CONTROL_PRIVATE_DATA mSmmControl;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16                          mABase;
+
+VOID
+EFIAPI
+DisablePendingSmis (
+  VOID
+  );
+
+/**
+  Fixup internal data pointers so that the services can be called in virtual mode.
+
+  @param[in] Event                The event registered.
+  @param[in] Context              Event context.
+
+**/
+VOID
+EFIAPI
+SmmControlVirtualAddressChangeEvent (
+  IN EFI_EVENT                  Event,
+  IN VOID                       *Context
+  )
+{
+  gRT->ConvertPointer (0, (VOID *) &(mSmmControl.SmmControl.Trigger));
+  gRT->ConvertPointer (0, (VOID *) &(mSmmControl.SmmControl.Clear));
+}
+
+/**
+  <b>SmmControl DXE RUNTIME Module Entry Point</b>\n
+  - <b>Introduction</b>\n
+    The SmmControl module is a DXE RUNTIME driver that provides a standard way
+    for other drivers to trigger software SMIs.
+
+  - @pre
+    - PCH Power Management I/O space base address has already been programmed.
+      If SmmControl Runtime DXE driver is run before Status Code Runtime Protocol
+      is installed and there is the need to use Status code in the driver, it will
+      be necessary to add EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID to the dependency file.
+    - EFI_SMM_BASE2_PROTOCOL
+      - Documented in the System Management Mode Core Interface Specification.
+
+  - @result
+    The SmmControl driver produces the EFI_SMM_CONTROL_PROTOCOL documented in
+    System Management Mode Core Interface Specification.
+
+  @param[in] ImageHandle          Handle for the image of this driver
+  @param[in] SystemTable          Pointer to the EFI System Table
+
+  @retval EFI_STATUS              Results of the installation of the SMM Control Protocol
+**/
+EFI_STATUS
+EFIAPI
+SmmControlDriverEntryInit (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+  EFI_EVENT   Event;
+
+  DEBUG ((DEBUG_INFO, "SmmControlDriverEntryInit() Start\n"));
+
+  //
+  // Get the Power Management I/O space base address. We assume that
+  // this base address has already been programmed if this driver is
+  // being run.
+  //
+  mABase = PmcGetAcpiBase ();
+
+  Status = EFI_SUCCESS;
+  if (mABase != 0) {
+    //
+    // Install the instance of the protocol
+    //
+    mSmmControl.Signature                       = SMM_CONTROL_PRIVATE_DATA_SIGNATURE;
+    mSmmControl.Handle                          = ImageHandle;
+
+    mSmmControl.SmmControl.Trigger              = Activate;
+    mSmmControl.SmmControl.Clear                = Deactivate;
+    mSmmControl.SmmControl.MinimumTriggerPeriod = 0;
+
+    //
+    // Install our protocol interfaces on the device's handle
+    //
+    Status = gBS->InstallMultipleProtocolInterfaces (
+                    &mSmmControl.Handle,
+                    &gEfiSmmControl2ProtocolGuid,
+                    &mSmmControl.SmmControl,
+                    NULL
+                    );
+  } else {
+    Status = EFI_DEVICE_ERROR;
+    return Status;
+  }
+
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  SmmControlVirtualAddressChangeEvent,
+                  NULL,
+                  &gEfiEventVirtualAddressChangeGuid,
+                  &Event
+                  );
+  //
+  // Disable any PCH SMIs that, for whatever reason, are asserted after the boot.
+  //
+  DisablePendingSmis ();
+
+  DEBUG ((DEBUG_INFO, "SmmControlDriverEntryInit() End\n"));
+
+  return Status;
+}
+
+/**
+  Trigger the software SMI
+
+  @param[in] Data                 The value to be set on the software SMI data port
+
+  @retval EFI_SUCCESS             Function completes successfully
+**/
+EFI_STATUS
+EFIAPI
+SmmTrigger (
+  IN UINT8   Data
+  )
+{
+  UINT32  OutputData;
+  UINT32  OutputPort;
+
+  //
+  // Enable the APMC SMI
+  //
+  OutputPort  = mABase + R_ACPI_IO_SMI_EN;
+  OutputData  = IoRead32 ((UINTN) OutputPort);
+  OutputData |= (B_ACPI_IO_SMI_EN_APMC | B_ACPI_IO_SMI_EN_GBL_SMI);
+  DEBUG (
+    (DEBUG_VERBOSE,
+     "The SMI Control Port at address %x will be written to %x.\n",
+     OutputPort,
+     OutputData)
+    );
+  IoWrite32 (
+    (UINTN) OutputPort,
+    (UINT32) (OutputData)
+    );
+
+  OutputPort  = R_PCH_IO_APM_CNT;
+  OutputData  = Data;
+
+  //
+  // Generate the APMC SMI
+  //
+  IoWrite8 (
+    (UINTN) OutputPort,
+    (UINT8) (OutputData)
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Clear the SMI status
+
+
+  @retval EFI_SUCCESS             The function completes successfully
+  @retval EFI_DEVICE_ERROR        Something error occurred
+**/
+EFI_STATUS
+EFIAPI
+SmmClear (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+  UINT32      OutputData;
+  UINT32      OutputPort;
+
+  Status = EFI_SUCCESS;
+
+  //
+  // Clear the Power Button Override Status Bit, it gates EOS from being set.
+  //
+  OutputPort  = mABase + R_ACPI_IO_PM1_STS;
+  OutputData  = B_ACPI_IO_PM1_STS_PRBTNOR;
+  DEBUG (
+    (DEBUG_VERBOSE,
+     "The PM1 Status Port at address %x will be written to %x.\n",
+     OutputPort,
+     OutputData)
+    );
+  IoWrite16 (
+    (UINTN) OutputPort,
+    (UINT16) (OutputData)
+    );
+
+  //
+  // Clear the APM SMI Status Bit
+  //
+  OutputPort  = mABase + R_ACPI_IO_SMI_STS;
+  OutputData  = B_ACPI_IO_SMI_STS_APM;
+  DEBUG (
+    (DEBUG_VERBOSE,
+     "The SMI Status Port at address %x will be written to %x.\n",
+     OutputPort,
+     OutputData)
+    );
+  IoWrite32 (
+    (UINTN) OutputPort,
+    (UINT32) (OutputData)
+    );
+
+  //
+  // Set the EOS Bit
+  //
+  OutputPort  = mABase + R_ACPI_IO_SMI_EN;
+  OutputData  = IoRead32 ((UINTN) OutputPort);
+  OutputData |= B_ACPI_IO_SMI_EN_EOS;
+  DEBUG (
+    (DEBUG_VERBOSE,
+     "The SMI Control Port at address %x will be written to %x.\n",
+     OutputPort,
+     OutputData)
+    );
+  IoWrite32 (
+    (UINTN) OutputPort,
+    (UINT32) (OutputData)
+    );
+
+  //
+  // There is no need to read EOS back and check if it is set.
+  // This can lead to a reading of zero if an SMI occurs right after the SMI_EN port read
+  // but before the data is returned to the CPU.
+  // SMM Dispatcher should make sure that EOS is set after all SMI sources are processed.
+  //
+  return Status;
+}
+
+/**
+  This routine generates an SMI
+
+  @param[in] This                       The EFI SMM Control protocol instance
+  @param[in, out] CommandPort           The buffer contains data to the command port
+  @param[in, out] DataPort              The buffer contains data to the data port
+  @param[in] Periodic                   Periodic or not
+  @param[in] ActivationInterval         Interval of periodic SMI
+
+  @retval EFI Status                    Describing the result of the operation
+  @retval EFI_INVALID_PARAMETER         Some parameter value passed is not supported
+**/
+EFI_STATUS
+EFIAPI
+Activate (
+  IN CONST EFI_SMM_CONTROL2_PROTOCOL                    * This,
+  IN OUT  UINT8                                         *CommandPort       OPTIONAL,
+  IN OUT  UINT8                                         *DataPort          OPTIONAL,
+  IN      BOOLEAN                                       Periodic           OPTIONAL,
+  IN      UINTN                                         ActivationInterval OPTIONAL
+  )
+{
+  EFI_STATUS  Status;
+  UINT8       Data;
+
+  if (Periodic) {
+    DEBUG ((DEBUG_WARN, "Invalid parameter\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (CommandPort == NULL) {
+    Data = 0xFF;
+  } else {
+    Data = *CommandPort;
+  }
+  //
+  // Clear any pending the APM SMI
+  //
+  Status = SmmClear ();
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  return SmmTrigger (Data);
+}
+
+/**
+  This routine clears an SMI
+
+  @param[in] This                 The EFI SMM Control protocol instance
+  @param[in] Periodic             Periodic or not
+
+  @retval EFI Status              Describing the result of the operation
+  @retval EFI_INVALID_PARAMETER   Some parameter value passed is not supported
+**/
+EFI_STATUS
+EFIAPI
+Deactivate (
+  IN CONST EFI_SMM_CONTROL2_PROTOCOL       *This,
+  IN  BOOLEAN                              Periodic OPTIONAL
+  )
+{
+  if (Periodic) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return SmmClear ();
+}
+/**
+  Disable all pending SMIs
+
+**/
+VOID
+EFIAPI
+DisablePendingSmis (
+  VOID
+  )
+{
+  UINT32               Data;
+  BOOLEAN              SciEn;
+
+  //
+  // Determine whether an ACPI OS is present (via the SCI_EN bit)
+  //
+  Data      = IoRead16 ((UINTN) mABase + R_ACPI_IO_PM1_CNT);
+  SciEn     = (BOOLEAN) ((Data & B_ACPI_IO_PM1_CNT_SCI_EN) == B_ACPI_IO_PM1_CNT_SCI_EN);
+
+  if (!SciEn) {
+    //
+    // Clear any SMIs that double as SCIs (when SCI_EN==0)
+    //
+    IoWrite16 ((UINTN) mABase + R_ACPI_IO_PM1_STS, 0xFFFF);
+    IoWrite16 ((UINTN) mABase + R_ACPI_IO_PM1_EN, 0);
+    IoWrite16 ((UINTN) mABase + R_ACPI_IO_PM1_CNT, 0);
+    IoWrite32 (
+      (UINTN) mABase + R_ACPI_IO_GPE0_STS_127_96,
+      (UINT32)( B_ACPI_IO_GPE0_STS_127_96_WADT |
+                B_ACPI_IO_GPE0_STS_127_96_USB_CON_DSX_STS |
+                B_ACPI_IO_GPE0_STS_127_96_LAN_WAKE |
+                B_ACPI_IO_GPE0_STS_127_96_PME_B0 |
+                B_ACPI_IO_GPE0_STS_127_96_PME |
+                B_ACPI_IO_GPE0_STS_127_96_BATLOW |
+                B_ACPI_IO_GPE0_STS_127_96_RI |
+                B_ACPI_IO_GPE0_STS_127_96_SWGPE)
+      );
+    IoWrite32 ((UINTN) mABase + R_ACPI_IO_GPE0_EN_127_96, (UINT32) B_ACPI_IO_GPE0_EN_127_96_WADT);
+  }
+  //
+  // Clear and disable all SMIs that are unaffected by SCI_EN
+  //
+  GpioDisableAllGpiSmi ();
+
+  GpioClearAllGpiSmiSts ();
+
+  IoWrite32 ((UINTN) mABase + R_ACPI_IO_DEVACT_STS, 0x0000FFFF);
+
+  IoWrite32 ((UINTN) mABase + R_ACPI_IO_SMI_STS, ~0u);
+
+  //
+  // (Make sure to write this register last -- EOS re-enables SMIs for the PCH)
+  //
+  Data  = IoRead32 ((UINTN) mABase + R_ACPI_IO_SMI_EN);
+  //
+  // clear all bits except those tied to SCI_EN
+  //
+  Data &= B_ACPI_IO_SMI_EN_BIOS_RLS;
+  //
+  // enable SMIs and specifically enable writes to APM_CNT.
+  //
+  Data |= B_ACPI_IO_SMI_EN_GBL_SMI | B_ACPI_IO_SMI_EN_APMC;
+  //
+  //  NOTE: Default value of EOS is set in PCH, it will be automatically cleared Once the PCH asserts SMI# low,
+  //  we don't need to do anything to clear it
+  //
+  IoWrite32 ((UINTN) mABase + R_ACPI_IO_SMI_EN, Data);
+}
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.h b/Silicon/Intel/TigerlakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.h
new file mode 100644
index 0000000000..af368e6945
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.h
@@ -0,0 +1,130 @@
+/** @file
+  Header file for SMM Control Driver.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SMM_CONTROL_DRIVER_H_
+#define _SMM_CONTROL_DRIVER_H_
+
+#include <Protocol/SmmControl2.h>
+
+
+#define SMM_CONTROL_PRIVATE_DATA_SIGNATURE  SIGNATURE_32 ('i', '4', 's', 'c')
+
+typedef struct {
+  UINTN                           Signature;
+  EFI_HANDLE                      Handle;
+  EFI_SMM_CONTROL2_PROTOCOL       SmmControl;
+} SMM_CONTROL_PRIVATE_DATA;
+
+#define SMM_CONTROL_PRIVATE_DATA_FROM_THIS(a) CR (a, SMM_CONTROL_PRIVATE_DATA, SmmControl, SMM_CONTROL_DEV_SIGNATURE)
+
+//
+// Prototypes
+//
+
+/**
+  <b>SmmControl DXE RUNTIME Module Entry Point</b>\n
+  - <b>Introduction</b>\n
+    The SmmControl module is a DXE RUNTIME driver that provides a standard way
+    for other drivers to trigger software SMIs.
+
+  - @pre
+    - PCH Power Management I/O space base address has already been programmed.
+      If SmmControl Runtime DXE driver is run before Status Code Runtime Protocol
+      is installed and there is the need to use Status code in the driver, it will
+      be necessary to add EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID to the dependency file.
+    - EFI_SMM_BASE2_PROTOCOL
+      - Documented in the System Management Mode Core Interface Specification.
+
+  - @result
+    The SmmControl driver produces the EFI_SMM_CONTROL_PROTOCOL documented in
+    System Management Mode Core Interface Specification.
+
+  @param[in] ImageHandle          Handle for the image of this driver
+  @param[in] SystemTable          Pointer to the EFI System Table
+
+  @retval EFI_STATUS              Results of the installation of the SMM Control Protocol
+**/
+EFI_STATUS
+EFIAPI
+SmmControlDriverEntryInit (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  );
+
+/**
+  Trigger the software SMI
+
+  @param[in] Data                 The value to be set on the software SMI data port
+
+  @retval EFI_SUCCESS             Function completes successfully
+**/
+EFI_STATUS
+EFIAPI
+SmmTrigger (
+  UINT8   Data
+  );
+
+/**
+  Clear the SMI status
+
+
+  @retval EFI_SUCCESS             The function completes successfully
+  @retval EFI_DEVICE_ERROR        Something error occurred
+**/
+EFI_STATUS
+EFIAPI
+SmmClear (
+  VOID
+  );
+
+/**
+  This routine generates an SMI
+
+  @param[in] This                       The EFI SMM Control protocol instance
+  @param[in, out] ArgumentBuffer        The buffer of argument
+  @param[in, out] ArgumentBufferSize    The size of the argument buffer
+  @param[in] Periodic                   Periodic or not
+  @param[in] ActivationInterval         Interval of periodic SMI
+
+  @retval EFI Status                    Describing the result of the operation
+  @retval EFI_INVALID_PARAMETER         Some parameter value passed is not supported
+**/
+EFI_STATUS
+EFIAPI
+Activate (
+  IN CONST EFI_SMM_CONTROL2_PROTOCOL    *This,
+  IN OUT  UINT8                         *ArgumentBuffer OPTIONAL,
+  IN OUT  UINT8                         *ArgumentBufferSize OPTIONAL,
+  IN      BOOLEAN                       Periodic OPTIONAL,
+  IN      UINTN                         ActivationInterval OPTIONAL
+  );
+
+/**
+  This routine clears an SMI
+
+  @param[in] This                 The EFI SMM Control protocol instance
+  @param[in] Periodic             Periodic or not
+
+  @retval EFI Status              Describing the result of the operation
+  @retval EFI_INVALID_PARAMETER   Some parameter value passed is not supported
+**/
+EFI_STATUS
+EFIAPI
+Deactivate (
+  IN CONST EFI_SMM_CONTROL2_PROTOCOL    *This,
+  IN       BOOLEAN                      Periodic OPTIONAL
+  );
+/**
+  Disable all pending SMIs
+
+**/
+VOID
+EFIAPI
+DisablePendingSmis (
+  VOID
+  );
+
+#endif
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 37/40] TigerlakeSiliconPkg/SystemAgent: Add SystemAgent modules
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (34 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 36/40] TigerlakeSiliconPkg/Pch: Add Pch modules Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 38/40] TigerlakeSiliconPkg/Fru: Add Fru DSC files Heng Luo
                   ` (2 subsequent siblings)
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * SystemAgent/SaInit/Dxe
  * SystemAgent/SaInit/Smm

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c          | 431 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c          | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h          |  58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c       | 181 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h       | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf     | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/CpuPcieSmm.c      | 454 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/SaLateInitSmm.c   | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/SaLateInitSmm.h   | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/SaLateInitSmm.inf |  72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 10 files changed, 1803 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
new file mode 100644
index 0000000000..d84a0c1fa4
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaAcpi.c
@@ -0,0 +1,431 @@
+/** @file
+  This is the driver that initializes the Intel System Agent.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "SaInitDxe.h"
+#include "SaInit.h"
+#include <SaConfigHob.h>
+#include <Protocol/SaNvsArea.h>
+#include <Library/PchInfoLib.h>
+#include <CpuPcieInfo.h>
+#include <Library/DxeCpuPcieRpLib.h>
+#include <SaConfigHob.h>
+#include <CpuPcieHob.h>
+#include <HostBridgeDataHob.h>
+#include <CpuDataStruct.h>
+
+///
+/// Global Variables
+///
+GLOBAL_REMOVE_IF_UNREFERENCED SYSTEM_AGENT_NVS_AREA_PROTOCOL  mSaNvsAreaProtocol;
+GLOBAL_REMOVE_IF_UNREFERENCED SA_POLICY_PROTOCOL              *mSaPolicy;
+extern SA_CONFIG_HOB                                          *mSaConfigHob;
+
+/**
+  A protocol callback which updates 64bits MMIO Base and Length in SA GNVS area
+**/
+VOID
+UpdateSaGnvsForMmioResourceBaseLength (
+  VOID
+  )
+{
+  EFI_PHYSICAL_ADDRESS      PciBaseAddress;
+  UINT32                    Tolud;
+  UINT64                    Length;
+  UINT64                    McD0BaseAddress;
+  UINTN                     ResMemLimit1;
+  UINT8                     EnableAbove4GBMmioBiosAssignemnt;
+  HOST_BRIDGE_DATA_HOB      *HostBridgeDataHob;
+
+  PciBaseAddress = 0;
+  Tolud = 0;
+  Length = 0;
+  ResMemLimit1 = 0;
+  EnableAbove4GBMmioBiosAssignemnt = 0;
+  HostBridgeDataHob = NULL;
+  //
+  // Read memory map registers
+  //
+  McD0BaseAddress        = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, 0);
+  Tolud                  = PciSegmentRead32 (McD0BaseAddress + R_SA_TOLUD) & B_SA_TOLUD_TOLUD_MASK;
+  PciBaseAddress         = Tolud;
+
+  ResMemLimit1 = (UINTN) PcdGet64 (PcdSiPciExpressBaseAddress);
+
+  Length = ResMemLimit1 - PciBaseAddress;
+
+  //
+  // Get HostBridgeData HOB and see if above 4GB MMIO BIOS assignment enabled
+  //
+  HostBridgeDataHob = (HOST_BRIDGE_DATA_HOB *) GetFirstGuidHob (&gHostBridgeDataHobGuid);
+  if ((HostBridgeDataHob != NULL) && (HostBridgeDataHob->EnableAbove4GBMmio == 1)) {
+    EnableAbove4GBMmioBiosAssignemnt = 1;
+  }
+
+  //
+  // Enable Above 4GB MMIO when Aperture Size is 2GB or higher
+  //
+  if ((mSaConfigHob != NULL) && (mSaConfigHob->ApertureSize >= 15)) {
+    EnableAbove4GBMmioBiosAssignemnt = 1;
+  }
+
+  //
+  // Check Enable Above 4GB MMIO or not
+  //
+
+  DEBUG ((DEBUG_INFO, "Update SA GNVS Area.\n"));
+  mSaNvsAreaProtocol.Area->Mmio32Base   = (UINT32) PciBaseAddress;
+  mSaNvsAreaProtocol.Area->Mmio32Length = (UINT32) Length;
+  if (EnableAbove4GBMmioBiosAssignemnt == 1) {
+    mSaNvsAreaProtocol.Area->Mmio64Base   = BASE_256GB;
+    mSaNvsAreaProtocol.Area->Mmio64Length = SIZE_256GB;
+  }
+  DEBUG ((DEBUG_INFO, "SaNvsAreaProtocol.Area->Mmio64Base = %lx\n", mSaNvsAreaProtocol.Area->Mmio64Base));
+  DEBUG ((DEBUG_INFO, "SaNvsAreaProtocol.Area->Mmio64Length = %lx\n", mSaNvsAreaProtocol.Area->Mmio64Length));
+  DEBUG ((DEBUG_INFO, "SaNvsAreaProtocol.Area->Mmio32Base = %lx\n", mSaNvsAreaProtocol.Area->Mmio32Base));
+  DEBUG ((DEBUG_INFO, "SaNvsAreaProtocol.Area->Mmio32Length = %lx\n", mSaNvsAreaProtocol.Area->Mmio32Length));
+}
+
+/**
+  Install SSDT Table
+
+  @retval EFI_SUCCESS - SSDT Table load successful.
+**/
+EFI_STATUS
+InstallSsdtAcpiTable (
+  IN GUID   SsdtTableGuid,
+  IN UINT64 Signature
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_HANDLE                    *HandleBuffer;
+  BOOLEAN                       LoadTable;
+  UINTN                         NumberOfHandles;
+  UINTN                         Index;
+  INTN                          Instance;
+  UINTN                         Size;
+  UINT32                        FvStatus;
+  UINTN                         TableHandle;
+  EFI_FV_FILETYPE               FileType;
+  EFI_FV_FILE_ATTRIBUTES        Attributes;
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
+  EFI_ACPI_TABLE_PROTOCOL       *AcpiTable;
+  EFI_ACPI_DESCRIPTION_HEADER   *TableHeader;
+  EFI_ACPI_COMMON_HEADER        *Table;
+
+  FwVol         = NULL;
+  Table         = NULL;
+
+  DEBUG ((DEBUG_INFO, "Loading SSDT Table GUID: %g\n", SsdtTableGuid));
+
+  ///
+  /// Locate FV protocol.
+  ///
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiFirmwareVolume2ProtocolGuid,
+                  NULL,
+                  &NumberOfHandles,
+                  &HandleBuffer
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Look for FV with ACPI storage file
+  ///
+  for (Index = 0; Index < NumberOfHandles; Index++) {
+    ///
+    /// Get the protocol on this handle
+    /// This should not fail because of LocateHandleBuffer
+    ///
+    Status = gBS->HandleProtocol (
+                    HandleBuffer[Index],
+                    &gEfiFirmwareVolume2ProtocolGuid,
+                    (VOID **) &FwVol
+                    );
+    ASSERT_EFI_ERROR (Status);
+    if (FwVol == NULL) {
+      return EFI_NOT_FOUND;
+    }
+    ///
+    /// See if it has the ACPI storage file
+    ///
+    Size      = 0;
+    FvStatus  = 0;
+    Status = FwVol->ReadFile (
+                      FwVol,
+                      &SsdtTableGuid,
+                      NULL,
+                      &Size,
+                      &FileType,
+                      &Attributes,
+                      &FvStatus
+                      );
+
+    ///
+    /// If we found it, then we are done
+    ///
+    if (!EFI_ERROR (Status)) {
+      break;
+    }
+  }
+  ///
+  /// Our exit status is determined by the success of the previous operations
+  /// If the protocol was found, Instance already points to it.
+  ///
+  ///
+  /// Free any allocated buffers
+  ///
+  FreePool (HandleBuffer);
+
+  ///
+  /// Sanity check that we found our data file
+  ///
+  ASSERT (FwVol);
+
+  ///
+  /// Locate ACPI tables
+  ///
+  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);
+
+  ///
+  /// Read tables from the storage file.
+  ///
+  if (FwVol == NULL) {
+    ASSERT_EFI_ERROR (EFI_NOT_FOUND);
+    return EFI_NOT_FOUND;
+  }
+  Instance = 0;
+
+  while (Status == EFI_SUCCESS) {
+    ///
+    /// Read the ACPI tables
+    ///
+    Status = FwVol->ReadSection (
+                      FwVol,
+                      &SsdtTableGuid,
+                      EFI_SECTION_RAW,
+                      Instance,
+                      (VOID **) &Table,
+                      &Size,
+                      &FvStatus
+                      );
+    if (!EFI_ERROR (Status)) {
+      ///
+      /// check and load HybridGraphics SSDT table
+      ///
+      LoadTable   = FALSE;
+      TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
+
+      if (((EFI_ACPI_DESCRIPTION_HEADER *) TableHeader)->OemTableId == Signature) {
+        ///
+        /// This is the SSDT table that match the Signature
+        ///
+        DEBUG ((DEBUG_INFO, "Found out SSDT Table GUID: %g\n", SsdtTableGuid));
+        LoadTable = TRUE;
+      }
+
+      ///
+      /// Add the table
+      ///
+      if (LoadTable) {
+        TableHandle = 0;
+        Status = AcpiTable->InstallAcpiTable (
+                              AcpiTable,
+                              TableHeader,
+                              TableHeader->Length,
+                              &TableHandle
+                              );
+      }
+      ///
+      /// Increment the instance
+      ///
+      Instance++;
+      Table = NULL;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function gets registered as a callback to perform Dmar Igd
+
+  @param[in] Event     - A pointer to the Event that triggered the callback.
+  @param[in] Context   - A pointer to private data registered with the callback function.
+**/
+VOID
+EFIAPI
+SaAcpiEndOfDxeCallback (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  )
+{
+  EFI_STATUS          Status;
+
+  if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, IGD_BUS_NUM, IGD_DEV_NUM, IGD_FUN_NUM, PCI_VENDOR_ID_OFFSET)) != 0xFFFF) {
+    Status = PostPmInitEndOfDxe ();
+    if (EFI_SUCCESS != Status) {
+      DEBUG ((DEBUG_WARN, "[SA] EndOfDxe GraphicsInit Error, Status = %r \n", Status));
+      ASSERT_EFI_ERROR (Status);
+    }
+  }
+
+  if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, IGD_BUS_NUM, IGD_DEV_NUM, IGD_FUN_NUM, PCI_VENDOR_ID_OFFSET)) != 0xFFFF) {
+    Status = GetVBiosVbtEndOfDxe ();
+    if (EFI_SUCCESS != Status) {
+      DEBUG ((DEBUG_WARN, "[SA] EndOfDxe Op Region Error, Status = %r \n", Status));
+    }
+
+    Status = UpdateIgdOpRegionEndOfDxe ();
+    if (EFI_SUCCESS != Status) {
+      DEBUG ((DEBUG_WARN, "[SA] EndOfDxe Update Op Region Error, Status = %r \n", Status));
+    }
+  }
+
+  return;
+}
+
+/**
+  SystemAgent Acpi Initialization.
+
+  @param[in] ImageHandle             Handle for the image of this driver
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_OUT_OF_RESOURCES    No enough buffer to allocate
+**/
+EFI_STATUS
+EFIAPI
+SaAcpiInit (
+  IN EFI_HANDLE         ImageHandle
+  )
+{
+  EFI_STATUS                Status;
+  EFI_CPUID_REGISTER        CpuidRegs;
+  EFI_EVENT                 EndOfDxeEvent;
+
+  CPU_PCIE_HOB              *CpuPcieHob;
+
+  AsmCpuid (1, &CpuidRegs.RegEax, 0, 0, 0);
+  ///
+  /// Get the platform setup policy.
+  ///
+  Status = gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID **) &mSaPolicy);
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Install System Agent Global NVS protocol
+  ///
+  DEBUG ((DEBUG_INFO, "Install SA GNVS protocol\n"));
+  Status = (gBS->AllocatePool) (EfiACPIMemoryNVS, sizeof (SYSTEM_AGENT_NVS_AREA), (VOID **) &mSaNvsAreaProtocol.Area);
+  ASSERT_EFI_ERROR (Status);
+  ZeroMem ((VOID *) mSaNvsAreaProtocol.Area, sizeof (SYSTEM_AGENT_NVS_AREA));
+  mSaNvsAreaProtocol.Area->XPcieCfgBaseAddress  = (UINT32) (PcdGet64 (PcdSiPciExpressBaseAddress));
+  mSaNvsAreaProtocol.Area->CpuIdInfo            = CpuidRegs.RegEax;
+
+  ///
+  /// Get CpuPcieHob HOB
+  ///
+  CpuPcieHob = NULL;
+  CpuPcieHob = (CPU_PCIE_HOB *) GetFirstGuidHob (&gCpuPcieHobGuid);
+  if (CpuPcieHob == NULL) {
+    DEBUG((DEBUG_ERROR, "CpuPcieHob not found\n"));
+    // @todo: Will add it back once it will get add into NVS library since currently it is failing for JSL
+    //ASSERT(CpuPcieHob != NULL);
+    //return EFI_NOT_FOUND;
+  } else {
+    mSaNvsAreaProtocol.Area->SlotSelection = CpuPcieHob->SlotSelection;
+    DEBUG((DEBUG_INFO, "RpEnabledMask == %x\n", CpuPcieHob->RpEnabledMask));
+    if (CpuPcieHob->RpEnabledMask == 0) {
+      DEBUG ((DEBUG_ERROR, "All CPU PCIe root ports are disabled!!\n"));
+    } else {
+      if (CpuPcieHob->RpEnabledMask & BIT0) {
+        mSaNvsAreaProtocol.Area->CpuPcieRp0Enable = 1;
+      }
+      if (CpuPcieHob->RpEnabledMask & BIT1) {
+        mSaNvsAreaProtocol.Area->CpuPcieRp1Enable = 1;
+      }
+      if (CpuPcieHob->RpEnabledMask & BIT2) {
+        mSaNvsAreaProtocol.Area->CpuPcieRp2Enable = 1;
+      }
+      if (CpuPcieHob->RpEnabledMask & BIT3) {
+        mSaNvsAreaProtocol.Area->CpuPcieRp3Enable = 1;
+      }
+    }
+    mSaNvsAreaProtocol.Area->MaxPegPortNumber = GetMaxCpuPciePortNum ();
+  }
+
+  mSaNvsAreaProtocol.Area->SimicsEnvironment = 0;
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gSaNvsAreaProtocolGuid,
+                  &mSaNvsAreaProtocol,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// GtPostInit Initialization
+  ///
+  DEBUG ((DEBUG_INFO, "Initializing GT ACPI tables\n"));
+  GraphicsInit (ImageHandle, mSaPolicy);
+
+  ///
+  /// Audio (dHDA) Initialization
+  ///
+  ///
+  /// Vtd Initialization
+  ///
+  DEBUG ((DEBUG_INFO, "Initializing VT-d ACPI tables\n"));
+  VtdInit (mSaPolicy);
+
+  ///
+  /// IgdOpRegion Install Initialization
+  ///
+  DEBUG ((DEBUG_INFO, "Initializing IGD OpRegion\n"));
+  IgdOpRegionInit ();
+
+  ///
+  /// Register an end of DXE event for SA ACPI to do tasks before invoking any UEFI drivers,
+  /// applications, or connecting consoles,...
+  ///
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  SaAcpiEndOfDxeCallback,
+                  NULL,
+                  &gEfiEndOfDxeEventGroupGuid,
+                  &EndOfDxeEvent
+                  );
+
+  ///
+  /// Install System Agent Global NVS ACPI table
+  ///
+  Status = InstallSsdtAcpiTable (gSaSsdtAcpiTableStorageGuid, SIGNATURE_64 ('S', 'a', 'S', 's', 'd', 't', ' ', 0));
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Update CPU PCIE RP NVS AREA
+  ///
+  UpdateCpuPcieNVS();
+  ///
+  /// Install Intel Graphics SSDT
+  ///
+  Status = InstallSsdtAcpiTable (gGraphicsAcpiTableStorageGuid, SIGNATURE_64 ('I','g','f','x','S','s','d','t'));
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Install IPU SSDT if IPU is present.
+  ///
+  if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, IPU_BUS_NUM, IPU_DEV_NUM, IPU_FUN_NUM, 0)) != V_SA_DEVICE_ID_INVALID) {
+      Status = InstallSsdtAcpiTable (gIpuAcpiTableStorageGuid, SIGNATURE_64 ('I','p','u','S','s','d','t',0));
+      ASSERT_EFI_ERROR (Status);
+
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
new file mode 100644
index 0000000000..5c0fea422b
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.c
@@ -0,0 +1,120 @@
+/** @file
+  This is the Common driver that initializes the Intel System Agent.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "SaInit.h"
+#include <Library/PciSegmentLib.h>
+#include <HostBridgeDataHob.h>
+#include <SaConfigHob.h>
+#include <Protocol/PciEnumerationComplete.h>
+
+///
+/// Global Variables
+///
+GLOBAL_REMOVE_IF_UNREFERENCED SA_CONFIG_HOB                          *mSaConfigHob;
+BOOLEAN                                                              mSkipPamLock = FALSE;
+
+/*
+  Intel(R) Core Processor Skylake BWG version 0.4.0
+
+  18.6 System Agent Configuration Locking
+   For reliable operation and security, System BIOS must set the following bits:
+   1. For all modern Intel processors, Intel strongly recommends that BIOS should set
+       the D_LCK bit. Set B0:D0:F0.R088h [4] = 1b to lock down SMRAM space.
+  BaseAddr values for mSaSecurityRegisters that uses PciExpressBaseAddress will be initialized at
+  Runtime inside function CpuPcieInitPolicy().
+*/
+GLOBAL_REMOVE_IF_UNREFERENCED BOOT_SCRIPT_REGISTER_SETTING mSaSecurityRegisters[] = {
+  {0,  R_SA_SMRAMC,  0xFFFFFFFF,  BIT4}
+};
+
+/**
+  SystemAgent Initialization Common Function.
+
+  @retval EFI_SUCCESS   - Always.
+**/
+
+VOID
+SaInitEntryPoint (
+  VOID
+  )
+{
+  HOST_BRIDGE_DATA_HOB        *HostBridgeDataHob;
+
+  ///
+  /// Get Host Bridge Data HOB
+  ///
+  HostBridgeDataHob = NULL;
+  HostBridgeDataHob = (HOST_BRIDGE_DATA_HOB *) GetFirstGuidHob (&gHostBridgeDataHobGuid);
+  if (HostBridgeDataHob != NULL) {
+    mSkipPamLock = HostBridgeDataHob->SkipPamLock;
+  }
+  return;
+}
+
+/**
+  This function does SA security lock
+**/
+VOID
+SaSecurityLock (
+  VOID
+  )
+{
+  UINT8           Index;
+  UINT64          BaseAddress;
+  UINT32          RegOffset;
+  UINT32          Data32And;
+  UINT32          Data32Or;
+
+  ///
+  /// 17.2 System Agent Security Lock configuration
+  ///
+  DEBUG ((DEBUG_INFO, "DXE SaSecurityLock\n"));
+  for (Index = 0; Index < (sizeof (mSaSecurityRegisters) / sizeof (BOOT_SCRIPT_REGISTER_SETTING)); Index++) {
+    BaseAddress = mSaSecurityRegisters[Index].BaseAddr;
+    RegOffset   = mSaSecurityRegisters[Index].Offset;
+    Data32And   = mSaSecurityRegisters[Index].AndMask;
+    Data32Or    = mSaSecurityRegisters[Index].OrMask;
+
+    if (RegOffset == R_SA_SMRAMC) {
+      ///
+      /// SMRAMC LOCK must use CF8/CFC access
+      ///
+      PciCf8Or8 (PCI_CF8_LIB_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC), (UINT8) Data32Or);
+      BaseAddress = S3_BOOT_SCRIPT_LIB_PCI_ADDRESS (SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_SMRAMC);
+      S3BootScriptSavePciCfgReadWrite (
+        S3BootScriptWidthUint8,
+        (UINTN) BaseAddress,
+        &Data32Or,
+        &Data32And
+        );
+    }
+  }
+
+}
+
+/**
+  This function performs SA Security locking in EndOfDxe callback
+
+  @retval EFI_SUCCESS     - Security lock has done
+  @retval EFI_UNSUPPORTED - Security lock not done successfully
+**/
+EFI_STATUS
+SaSecurityInit (
+  VOID
+  )
+{
+
+  UINT8                     Index;
+
+  for (Index = 0; Index < (sizeof (mSaSecurityRegisters) / sizeof (BOOT_SCRIPT_REGISTER_SETTING)); Index++) {
+    if (mSaSecurityRegisters[Index].BaseAddr != PcdGet64 (PcdMchBaseAddress)) {
+      mSaSecurityRegisters[Index].BaseAddr = PcdGet64 (PcdSiPciExpressBaseAddress);
+    }
+  }
+  SaSecurityLock ();
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
new file mode 100644
index 0000000000..5c8f7dfd5f
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInit.h
@@ -0,0 +1,58 @@
+/** @file
+  Header file for SA Common Initialization Driver.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SA_INITIALIZATION_DRIVER_H_
+#define _SA_INITIALIZATION_DRIVER_H_
+
+#include <Uefi.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/Pci.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciCf8Lib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/SaPlatformLib.h>
+#include <Guid/EventGroup.h>
+#include <Protocol/SaPolicy.h>
+#include <Register/SaRegsHostBridge.h>
+#include <SaConfigHob.h>
+
+extern SA_POLICY_PROTOCOL              *mSaPolicy;
+extern SA_CONFIG_HOB                   *SaConfigHob;
+
+typedef struct {
+  UINT64  BaseAddr;
+  UINT32  Offset;
+  UINT32  AndMask;
+  UINT32  OrMask;
+} BOOT_SCRIPT_REGISTER_SETTING;
+
+/**
+  SystemAgent Initialization Common Function.
+
+  @retval EFI_SUCCESS   - Always.
+**/
+VOID
+SaInitEntryPoint (
+  VOID
+  );
+
+/**
+  This function performs SA Security locking in EndOfDxe callback
+
+  @retval EFI_SUCCESS     - Security lock has done
+  @retval EFI_UNSUPPORTED - Security lock not done successfully
+**/
+EFI_STATUS
+SaSecurityInit (
+  VOID
+  );
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
new file mode 100644
index 0000000000..2a0e0accf5
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.c
@@ -0,0 +1,181 @@
+/** @file
+  This is the driver that initializes the Intel System Agent.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "SaInitDxe.h"
+#include "SaInit.h"
+#include <SaConfigHob.h>
+#include <Protocol/PciEnumerationComplete.h>
+#include <MemInfoHob.h>
+#include <Protocol/SaIotrapSmi.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16                   mPcieIoTrapAddress;
+
+///
+/// Global Variables
+///
+extern SA_CONFIG_HOB         *mSaConfigHob;
+
+
+/**
+  SystemAgent Dxe Initialization.
+
+  @param[in] ImageHandle             Handle for the image of this driver
+  @param[in] SystemTable             Pointer to the EFI System Table
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_OUT_OF_RESOURCES    No enough buffer to allocate
+**/
+EFI_STATUS
+EFIAPI
+SaInitEntryPointDxe (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS                Status;
+  VOID                      *Registration;
+  EFI_EVENT                 ReadyToBoot;
+
+
+  DEBUG ((DEBUG_INFO, "SaInitDxe Start\n"));
+
+  SaInitEntryPoint ();
+
+  Status = SaAcpiInit (ImageHandle);
+  ///
+  /// Create PCI Enumeration Completed callback for CPU PCIe
+  ///
+  EfiCreateProtocolNotifyEvent (
+    &gEfiPciEnumerationCompleteProtocolGuid,
+    TPL_CALLBACK,
+    CpuPciEnumCompleteCallback,
+    NULL,
+    &Registration
+    );
+
+  //
+  // Register a Ready to boot event to config PCIE power management setting after OPROM executed
+  //
+  Status = EfiCreateEventReadyToBootEx (
+             TPL_CALLBACK,
+             SaOnReadyToBoot,
+             NULL,
+             &ReadyToBoot
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "SaInitDxe End\n"));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Do PCIE power management while resume from S3
+**/
+VOID
+ReconfigureCpuPciePowerManagementForS3 (
+  VOID
+  )
+{
+  EFI_STATUS                            Status;
+  UINT32                                Data32;
+  SA_IOTRAP_SMI_PROTOCOL                *CpuPcieIoTrapProtocol;
+
+  Status = gBS->LocateProtocol (&gCpuPcieIoTrapProtocolGuid, NULL, (VOID **) &CpuPcieIoTrapProtocol);
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+  mPcieIoTrapAddress = CpuPcieIoTrapProtocol->SaIotrapSmiAddress;
+  DEBUG ((DEBUG_INFO, "PcieIoTrapAddress: %0x\n", mPcieIoTrapAddress));
+
+  if (mPcieIoTrapAddress != 0) {
+    //
+    // Save PCH PCIE IoTrap address to re-config PCIE power management setting after resume from S3
+    //
+    Data32 = CpuPciePmTrap;
+    S3BootScriptSaveIoWrite (
+      S3BootScriptWidthUint32,
+      (UINTN) (mPcieIoTrapAddress),
+      1,
+      &Data32
+      );
+  } else {
+    ASSERT (FALSE);
+  }
+}
+
+
+/**
+  SA initialization before boot to OS
+
+  @param[in] Event                A pointer to the Event that triggered the callback.
+  @param[in] Context              A pointer to private data registered with the callback function.
+**/
+VOID
+EFIAPI
+SaOnReadyToBoot (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  )
+{
+  DEBUG ((DEBUG_INFO, "Uefi SaOnReadyToBoot() Start\n"));
+
+  if (Event != NULL) {
+    gBS->CloseEvent (Event);
+  }
+
+  //
+  // Trigger an Iotrap SMI to config PCIE power management setting after PCI enumrate is done
+  //
+#if FixedPcdGetBool(PcdCpuPcieEnable) == 1
+  if (mPcieIoTrapAddress != 0) {
+    IoWrite32 ((UINTN) mPcieIoTrapAddress, CpuPciePmTrap);
+  } else {
+    ASSERT (FALSE);
+  }
+#endif
+  DEBUG ((DEBUG_INFO, "Uefi SaOnReadyToBoot() End\n"));
+}
+
+
+/**
+  This function gets registered as a callback to perform CPU PCIe initialization before EndOfDxe
+
+  @param[in] Event     - A pointer to the Event that triggered the callback.
+  @param[in] Context   - A pointer to private data registered with the callback function.
+**/
+VOID
+EFIAPI
+CpuPciEnumCompleteCallback (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  )
+{
+  EFI_STATUS          Status;
+  VOID                *ProtocolPointer;
+
+  DEBUG ((DEBUG_INFO, "CpuPciEnumCompleteCallback Start\n"));
+  ///
+  /// Check if this is first time called by EfiCreateProtocolNotifyEvent() or not,
+  /// if it is, we will skip it until real event is triggered
+  ///
+  Status = gBS->LocateProtocol (&gEfiPciEnumerationCompleteProtocolGuid, NULL, (VOID **) &ProtocolPointer);
+  if (EFI_SUCCESS != Status) {
+    return;
+  }
+
+  gBS->CloseEvent (Event);
+
+  ReconfigureCpuPciePowerManagementForS3();
+  //
+  // Routine for update DMAR
+  //
+  UpdateDmarEndOfPcieEnum ();
+
+  UpdateSaGnvsForMmioResourceBaseLength ();
+  DEBUG ((DEBUG_INFO, "CpuPciEnumCompleteCallback End\n"));
+  return;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
new file mode 100644
index 0000000000..7110d049a8
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.h
@@ -0,0 +1,136 @@
+/** @file
+  Header file for SA Initialization Driver.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SA_INIT_DXE_DRIVER_H_
+#define _SA_INIT_DXE_DRIVER_H_
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/AcpiTable.h>
+#include <Library/DxeVtdInitLib.h>
+#include <Library/DxeIgdOpRegionInitLib.h>
+#include <Library/DxeGraphicsInitLib.h>
+#include <Register/SaRegsHostBridge.h>
+
+///
+/// Driver Consumed Protocol Prototypes
+///
+#include <Protocol/SaPolicy.h>
+
+extern EFI_GUID gSaAcpiTableStorageGuid;
+extern EFI_GUID gSaSsdtAcpiTableStorageGuid;
+
+typedef struct {
+  UINT64                Address;
+  EFI_BOOT_SCRIPT_WIDTH Width;
+  UINT32                Value;
+} BOOT_SCRIPT_PCI_REGISTER_SAVE;
+
+///
+/// Function Prototype
+///
+/**
+  This function gets registered as a callback to perform CPU PCIe initialization before ExitPmAuth
+
+  @param[in] Event     - A pointer to the Event that triggered the callback.
+  @param[in] Context   - A pointer to private data registered with the callback function.
+
+**/
+VOID
+EFIAPI
+CpuPciEnumCompleteCallback (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  );
+
+/**
+  <b>System Agent Initialization DXE Driver Entry Point</b>
+  - <b>Introduction</b> \n
+    Based on the information/data in SA_POLICY_PROTOCOL, this module performs further SA initialization in DXE phase,
+    e.g. internal devices enable/disable, SSVID/SID programming, graphic power-management, VT-d, IGD OpRegion initialization.
+    From the perspective of a PCI Express hierarchy, the Broadwell System Agent and PCH together appear as a Root Complex with root ports the number of which depends on how the 8 PCH ports and 4 System Agent PCIe ports are configured [4x1, 2x8, 1x16].
+    There is an internal link (DMI or OPI) that connects the System Agent to the PCH component. This driver includes initialization of SA DMI, PCI Express, SA & PCH Root Complex Topology.
+    For iGFX, this module implements the initialization of the Graphics Technology Power Management from the Broadwell System Agent BIOS Specification and the initialization of the IGD OpRegion/Software SCI - BIOS Specification.
+    The ASL files that go along with the driver define the IGD OpRegion mailboxes in ACPI space and implement the software SCI interrupt mechanism.
+    The IGD OpRegion/Software SCI code serves as a communication interface between system BIOS, ASL, and Intel graphics driver including making a block of customizable data (VBT) from the Intel video BIOS available.
+    Reference Code for the SCI service functions "Get BIOS Data" and "System BIOS Callback" can be found in the ASL files, those functions can be platform specific, the sample provided in the reference code are implemented for Intel CRB.
+    This module implements the VT-d functionality described in the Broadwell System Agent BIOS Specification.
+    This module publishes the LegacyRegion protocol to control the read and write accesses to the Legacy BIOS ranges.
+    E000 and F000 segments are the legacy BIOS ranges and contain pointers to the ACPI regions, SMBIOS tables and so on. This is a private protocol used by Intel Framework.
+    This module registers CallBack function that performs SA security registers lockdown at end of post as required from Broadwell Bios Spec.
+    In addition, this module publishes the SaInfo Protocol with information such as current System Agent reference code version#.
+
+  - @pre
+    - EFI_FIRMWARE_VOLUME_PROTOCOL: Documented in Firmware Volume Specification, available at the URL: http://www.intel.com/technology/framework/spec.htm
+    - SA_POLICY_PROTOCOL: A protocol published by a platform DXE module executed earlier; this is documented in this document as well.
+    - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL: Documented in the Unified Extensible Firmware Interface Specification, version 2.0, available at the URL: http://www.uefi.org/specs/
+    - EFI_BOOT_SCRIPT_SAVE_PROTOCOL: A protocol published by a platform DXE module executed earlier; refer to the Sample Code section of the Framework PCH Reference Code.
+    - EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL: Documented in the Unified Extensible Firmware Interface Specification, version 2.0, available at the URL: http://www.uefi.org/specs/
+    - EFI_ACPI_TABLE_PROTOCOL : Documented in PI Specification 1.2
+    - EFI_CPU_IO_PROTOCOL: Documented in CPU I/O Protocol Specification, available at the URL: http://www.intel.com/technology/framework/spec.htm
+    - EFI_DATA_HUB_PROTOCOL: Documented in EFI Data Hub Infrastructure Specification, available at the URL: http://www.intel.com/technology/framework/spec.htm
+    - EFI_HII_PROTOCOL (or EFI_HII_DATABASE_PROTOCOL for UEFI 2.1): Documented in Human Interface Infrastructure Specification, available at the URL: http://www.intel.com/technology/framework/spec.htm
+    (For EFI_HII_DATABASE_PROTOCOL, refer to UEFI Specification Version 2.1 available at the URL: http://www.uefi.org/)
+
+  - @result
+    IGD power-management functionality is initialized;  VT-d is initialized (meanwhile, the DMAR table is updated); IGD OpRegion is initialized - IGD_OPREGION_PROTOCOL installed, IGD OpRegion allocated and mailboxes initialized, chipset initialized and ready to generate Software SCI for Internal graphics events. Publishes the SA_INFO_PROTOCOL with current SA reference code version #. Publishes the EFI_LEGACY_REGION_PROTOCOL documented in the Compatibility Support Module Specification, version 0.9, available at the URL: http://www.intel.com/technology/framework/spec.htm
+
+  - <b>References</b> \n
+    IGD OpRegion/Software SCI for Broadwell
+    Advanced Configuration and Power Interface Specification Revision 4.0a.
+
+  - <b>Porting Recommendations</b> \n
+    No modification of the DXE driver should be typically necessary.
+    This driver should be executed after all related devices (audio, video, ME, etc.) are initialized to ensure correct data in DMAR table and DMA-remapping registers.
+
+  @param[in] ImageHandle             Handle for the image of this driver
+  @param[in] SystemTable             Pointer to the EFI System Table
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_OUT_OF_RESOURCES    No enough buffer to allocate
+**/
+EFI_STATUS
+EFIAPI
+SaInitEntryPointDxe (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  );
+
+/**
+  SystemAgent Acpi Initialization.
+
+  @param[in] ImageHandle             Handle for the image of this driver
+
+  @retval EFI_SUCCESS             The function completed successfully
+  @retval EFI_OUT_OF_RESOURCES    No enough buffer to allocate
+**/
+EFI_STATUS
+EFIAPI
+SaAcpiInit (
+  IN EFI_HANDLE         ImageHandle
+  );
+
+/**
+  A protocol callback which updates 64bits MMIO Base and Length in SA GNVS area
+**/
+VOID
+UpdateSaGnvsForMmioResourceBaseLength (
+  VOID
+  );
+
+/**
+  SA initialization before boot to OS
+
+  @param[in] Event                A pointer to the Event that triggered the callback.
+  @param[in] Context              A pointer to private data registered with the callback function.
+**/
+VOID
+EFIAPI
+SaOnReadyToBoot (
+  IN EFI_EVENT    Event,
+  IN VOID         *Context
+  );
+
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
new file mode 100644
index 0000000000..d23ba0fa3b
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Dxe/SaInitDxe.inf
@@ -0,0 +1,117 @@
+## @file
+# Component description file for SystemAgent Initialization driver
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = SaInitDxe
+FILE_GUID = DE23ACEE-CF55-4fb6-AA77-984AB53DE811
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_DRIVER
+ENTRY_POINT = SaInitEntryPointDxe
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+
+
+[LibraryClasses]
+UefiDriverEntryPoint
+UefiLib
+UefiBootServicesTableLib
+DxeServicesTableLib
+DebugLib
+PciCf8Lib
+PciSegmentLib
+BaseMemoryLib
+MemoryAllocationLib
+IoLib
+S3BootScriptLib
+PmcLib
+PchInfoLib
+GpioLib
+ConfigBlockLib
+SaPlatformLib
+PchPcieRpLib
+DxeGraphicsInitLib
+DxeIgdOpRegionInitLib
+DxeVtdInitLib
+PciExpressHelpersLib
+DxeCpuPcieRpLib
+SataLib
+
+[Packages]
+TigerlakeSiliconPkg/SiPkg.dec
+MdePkg/MdePkg.dec
+UefiCpuPkg/UefiCpuPkg.dec
+IntelSiliconPkg/IntelSiliconPkg.dec
+
+[Pcd]
+gSiPkgTokenSpaceGuid.PcdSiPciExpressBaseAddress
+gSiPkgTokenSpaceGuid.PcdMchBaseAddress
+gSiPkgTokenSpaceGuid.PcdSiIoApicBaseAddress
+gSiPkgTokenSpaceGuid.PcdCpuPcieEnable                  ## CONSUMES
+
+[FixedPcd]
+
+[Sources]
+SaInitDxe.h
+SaInitDxe.c
+SaInit.h
+SaInit.c
+SaAcpi.c
+
+
+[Protocols]
+gEfiAcpiTableProtocolGuid              ## CONSUMES
+gSaNvsAreaProtocolGuid                 ## PRODUCES
+gSaPolicyProtocolGuid                  ## CONSUMES
+gEfiCpuArchProtocolGuid                ## CONSUMES
+gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES
+gEfiPciRootBridgeIoProtocolGuid        ## CONSUMES
+gIgdOpRegionProtocolGuid               ## PRODUCES
+gEfiFirmwareVolume2ProtocolGuid        ## CONSUMES
+gGopComponentName2ProtocolGuid         ## CONSUMES
+gSaIotrapSmiProtocolGuid               ## CONSUMES
+gCpuPcieIoTrapProtocolGuid             ## CONSUMES
+
+[Guids]
+gSaConfigHobGuid
+gHgAcpiTablePchStorageGuid
+gSaAcpiTableStorageGuid
+gHgAcpiTableStorageGuid
+gSaSsdtAcpiTableStorageGuid
+gSegSsdtAcpiTableStorageGuid
+gTcssSsdtAcpiTableStorageGuid
+gGraphicsAcpiTableStorageGuid
+gIpuAcpiTableStorageGuid
+gEfiEndOfDxeEventGroupGuid
+gSiConfigHobGuid        ## CONSUMES
+gGraphicsDxeConfigGuid
+gMemoryDxeConfigGuid
+gPcieDxeConfigGuid
+gPchInfoHobGuid
+gTcssHobGuid
+gSaConfigHobGuid
+gSaDataHobGuid
+gCpuPcieHobGuid
+gHostBridgeDataHobGuid
+gVmdInfoHobGuid                   ## CONSUMES
+
+[FixedPcd]
+
+[Depex]
+gEfiAcpiTableProtocolGuid AND
+gEfiFirmwareVolume2ProtocolGuid AND
+gSaPolicyProtocolGuid AND
+gEfiPciRootBridgeIoProtocolGuid AND
+gEfiPciHostBridgeResourceAllocationProtocolGuid AND # This is to ensure that PCI MMIO resource has been prepared and available for this driver to allocate.
+gEfiHiiDatabaseProtocolGuid
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/CpuPcieSmm.c b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/CpuPcieSmm.c
new file mode 100644
index 0000000000..70d47e787f
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/CpuPcieSmm.c
@@ -0,0 +1,454 @@
+/** @file
+  CPU PCIe SMM Driver Entry
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "SaLateInitSmm.h"
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <PcieRegs.h>
+#include <Register/PchRegs.h>
+#include <Register/CpuPcieRegs.h>
+#include <Library/PcieHelperLib.h>
+#include <CpuPcieInfo.h>
+#include <Library/TimerLib.h>
+#include <Library/PciExpressHelpersLib.h>
+#include <Library/CpuPcieInfoFruLib.h>
+#include <CpuPcieConfig.h>
+#include <Library/CpuPcieRpLib.h>
+#include <Protocol/PchPcieSmiDispatch.h>
+#include <Protocol/PchSmiDispatch.h>
+#include <Protocol/SaIotrapSmi.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <CpuPcieHob.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8                       mSaBusNumber;
+//
+// @note:
+// These temp bus numbers cannot be used in runtime (hot-plug).
+// These can be used only during boot.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8                       mTempRootPortBusNumMin;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8                       mTempRootPortBusNumMax;
+GLOBAL_REMOVE_IF_UNREFERENCED CPU_PCIE_ROOT_PORT_CONFIG   mCpuPcieRootPortConfig[CPU_PCIE_MAX_ROOT_PORTS];
+GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN                     mCpuPciePmTrapExecuted = FALSE;
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_PCIE_DEVICE_OVERRIDE    *mDevAspmOverride;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32                      mNumOfDevAspmOverride;
+
+/**
+  An IoTrap callback to config PCIE power management settings
+**/
+VOID
+CpuPciePmIoTrapSmiCallback (
+  VOID
+  )
+{
+  UINT32                                    PortIndex;
+  UINT64                                    RpBase;
+  UINT8                                     MaxPciePortNum;
+  UINTN                                     RpDevice;
+  UINTN                                     RpFunction;
+
+  MaxPciePortNum = GetMaxCpuPciePortNum ();
+
+  for (PortIndex = 0; PortIndex < MaxPciePortNum; PortIndex++) {
+    GetCpuPcieRpDevFun (PortIndex, &RpDevice, &RpFunction);
+    RpBase = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, (UINT32) RpDevice, (UINT32) RpFunction, 0);
+
+    if (PciSegmentRead16 (RpBase) != 0xFFFF) {
+      mDevAspmOverride                  = NULL;
+      mNumOfDevAspmOverride             = 0;
+      RootportDownstreamPmConfiguration (
+        SA_SEG_NUM,
+        SA_MC_BUS,
+        (UINT8)RpDevice,
+        (UINT8)RpFunction,
+        mTempRootPortBusNumMin,
+        mTempRootPortBusNumMax,
+        &mCpuPcieRootPortConfig[PortIndex].PcieRpCommonConfig,
+        mNumOfDevAspmOverride,
+        mDevAspmOverride
+      );
+
+    }
+  }
+}
+
+/**
+  Program Common Clock and ASPM of Downstream Devices
+
+  @param[in] PortIndex                  Pcie Root Port Number
+  @param[in] RpDevice                   Pcie Root Pci Device Number
+  @param[in] RpFunction                 Pcie Root Pci Function Number
+
+  @retval EFI_SUCCESS                   Root port complete successfully
+  @retval EFI_UNSUPPORTED               PMC has invalid vendor ID
+**/
+EFI_STATUS
+CpuPcieSmi (
+  IN  UINT8                             PortIndex,
+  IN  UINT8                             RpDevice,
+  IN  UINT8                             RpFunction
+  )
+{
+  UINT8                 SecBus;
+  UINT8                 SubBus;
+  UINT64                RpBase;
+  UINT64                EpBase;
+  UINT8                 EpPcieCapPtr;
+  UINT8                 EpMaxSpeed;
+  BOOLEAN               DownstreamDevicePresent;
+  UINT32                Timeout;
+  UINT32                MaxLinkSpeed;
+
+  RpBase   = PCI_SEGMENT_LIB_ADDRESS (
+               SA_SEG_NUM,
+               SA_MC_BUS,
+               (UINT32) RpDevice,
+               (UINT32) RpFunction,
+               0
+               );
+
+  if (PciSegmentRead16 (RpBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+    DEBUG((DEBUG_INFO, "PCIe controller is disabled, return!!\n"));
+    return EFI_SUCCESS;
+  }
+  //
+  // Check presence detect state. Here the endpoint must be detected using PDS rather than
+  // the usual LinkActive check, because PDS changes immediately and LA takes a few milliseconds to stabilize
+  //
+  DownstreamDevicePresent = !!(PciSegmentRead16 (RpBase + R_PCIE_SLSTS) & B_PCIE_SLSTS_PDS);
+
+  if (DownstreamDevicePresent) {
+    ///
+    /// Make sure the link is active before trying to talk to device behind it
+    /// Wait up to 100ms, according to PCIE spec chapter 6.7.3.3
+    ///
+    Timeout = 100 * 1000;
+    while (CpuPcieIsLinkActive(RpBase) == 0) {
+      MicroSecondDelay (10);
+      Timeout-=10;
+      if (Timeout == 0) {
+        DEBUG((DEBUG_INFO, "PDS set but timeout while waiting for LA bit to get set!!!\n"));
+        return EFI_NOT_FOUND;
+      }
+    }
+    SecBus  = PciSegmentRead8 (RpBase + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+    SubBus  = PciSegmentRead8 (RpBase + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
+    ASSERT (SecBus != 0 && SubBus != 0);
+    if (SecBus == 0) {
+      DEBUG((DEBUG_INFO, "Secondary Bus is 0, return!!!\n"));
+      return EFI_NOT_FOUND;
+    }
+    RootportDownstreamConfiguration (
+      SA_SEG_NUM,
+      SA_MC_BUS,
+      RpDevice,
+      RpFunction,
+      mTempRootPortBusNumMin,
+      mTempRootPortBusNumMax,
+      EnumCpuPcie
+      );
+    RootportDownstreamPmConfiguration (
+      SA_SEG_NUM,
+      SA_MC_BUS,
+      RpDevice,
+      RpFunction,
+      mTempRootPortBusNumMin,
+      mTempRootPortBusNumMax,
+      &mCpuPcieRootPortConfig[PortIndex].PcieRpCommonConfig,
+      mNumOfDevAspmOverride,
+      mDevAspmOverride
+    );
+    //
+    // Perform Equalization
+    //
+    EpBase = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SecBus, 0, 0, 0);
+    EpPcieCapPtr = PcieFindCapId (SA_SEG_NUM, SecBus, 0, 0, EFI_PCI_CAPABILITY_ID_PCIEXP);
+    EpMaxSpeed = PciSegmentRead8 (EpBase + EpPcieCapPtr + R_PCIE_LCAP_OFFSET) & B_PCIE_LCAP_MLS;
+    MaxLinkSpeed = CpuPcieGetMaxLinkSpeed (RpBase);
+    if (EpMaxSpeed < MaxLinkSpeed) {
+        MaxLinkSpeed = EpMaxSpeed;
+    }
+    if (EpMaxSpeed >= V_PCIE_LCAP_MLS_GEN3 && EpMaxSpeed <= V_PCIE_LCAP_MLS_GEN4) {
+      PciSegmentAndThenOr16 (RpBase + R_PCIE_LCTL2, (UINT16)~B_PCIE_LCTL2_TLS, (UINT16)MaxLinkSpeed);
+      PciSegmentOr32 (RpBase + R_PCIE_LCTL3, B_PCIE_LCTL3_PE);
+      PciSegmentOr32 (RpBase + R_PCIE_LCTL, B_PCIE_LCTL_RL);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  PCIE Hotplug SMI call back function for each Root port
+
+  @param[in] DispatchHandle             Handle of this dispatch function
+  @param[in] RpContext                  Rootport context, which contains RootPort Index,
+                                        and RootPort PCI BDF.
+**/
+VOID
+EFIAPI
+CpuPcieSmiRpHandlerFunction (
+  IN  EFI_HANDLE                        DispatchHandle,
+  IN  PCH_PCIE_SMI_RP_CONTEXT           *RpContext
+  )
+{
+  CpuPcieSmi (RpContext->RpIndex, RpContext->DevNum, RpContext->FuncNum);
+}
+
+/**
+  PCIE Link Active State Change Hotplug SMI call back function for all Root ports
+
+  @param[in] DispatchHandle             Handle of this dispatch function
+  @param[in] RpContext                  Rootport context, which contains RootPort Index,
+                                        and RootPort PCI BDF.
+**/
+VOID
+EFIAPI
+CpuPcieLinkActiveStateChange (
+  IN  EFI_HANDLE                        DispatchHandle,
+  IN  PCH_PCIE_SMI_RP_CONTEXT           *RpContext
+  )
+{
+  return;
+}
+
+/**
+  PCIE Link Equalization Request SMI call back function for all Root ports
+
+  @param[in] DispatchHandle             Handle of this dispatch function
+  @param[in] RpContext                  Rootport context, which contains RootPort Index,
+                                        and RootPort PCI BDF.
+**/
+VOID
+EFIAPI
+CpuPcieLinkEqHandlerFunction (
+  IN  EFI_HANDLE                        DispatchHandle,
+  IN  PCH_PCIE_SMI_RP_CONTEXT           *RpContext
+  )
+{
+  ///
+  /// From PCI Express specification, the PCIe device can request for Link Equalization. When the
+  /// Link Equalization is requested by the device, an SMI will be generated  by PCIe RP when
+  /// enabled and the SMI subroutine would invoke the Software Preset/Coefficient Search
+  /// software to re-equalize the link.
+  ///
+
+  return;
+
+}
+/**
+  An IoTrap callback to config PCIE power management settings
+
+  @param[in] DispatchHandle  - The handle of this callback, obtained when registering
+  @param[in] DispatchContext - Pointer to the EFI_SMM_IO_TRAP_DISPATCH_CALLBACK_CONTEXT
+
+**/
+VOID
+EFIAPI
+CpuPcieIoTrapSmiCallback (
+  IN  EFI_HANDLE                            DispatchHandle,
+  IN  EFI_SMM_IO_TRAP_CONTEXT               *CallbackContext,
+  IN OUT VOID                               *CommBuffer,
+  IN OUT UINTN                              *CommBufferSize
+  )
+{
+  if (CallbackContext->WriteData == CpuPciePmTrap) {
+    if (mCpuPciePmTrapExecuted == FALSE) {
+      CpuPciePmIoTrapSmiCallback ();
+      mCpuPciePmTrapExecuted = TRUE;
+    }
+  } else {
+    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+  }
+}
+
+/**
+  This function clear the Io trap executed flag before enter S3
+
+  @param[in] Handle    Handle of the callback
+  @param[in] Context   The dispatch context
+
+  @retval EFI_SUCCESS  SA register saved
+**/
+EFI_STATUS
+EFIAPI
+CpuPcieS3EntryCallBack (
+  IN  EFI_HANDLE                   Handle,
+  IN CONST VOID                    *Context OPTIONAL,
+  IN OUT VOID                      *CommBuffer OPTIONAL,
+  IN OUT UINTN                     *CommBufferSize OPTIONAL
+  )
+{
+  mCpuPciePmTrapExecuted = FALSE;
+  return EFI_SUCCESS;
+}
+
+/**
+  Register PCIE Hotplug SMI dispatch function to handle Hotplug enabling
+
+  @param[in] ImageHandle          The image handle of this module
+  @param[in] SystemTable          The EFI System Table
+
+  @retval EFI_SUCCESS             The function completes successfully
+**/
+EFI_STATUS
+EFIAPI
+InitializeCpuPcieSmm (
+  IN      EFI_HANDLE            ImageHandle,
+  IN      EFI_SYSTEM_TABLE      *SystemTable
+  )
+{
+  EFI_STATUS                            Status;
+  UINT8                                 PortIndex;
+  UINT8                                 Data8;
+  UINT32                                Data32Or;
+  UINT32                                Data32And;
+  UINT64                                RpBase;
+  UINTN                                 RpDevice;
+  UINTN                                 RpFunction;
+  EFI_HANDLE                            PcieHandle;
+  EFI_HANDLE                            PchIoTrapHandle;
+  PCH_PCIE_SMI_DISPATCH_PROTOCOL        *PchPcieSmiDispatchProtocol;
+  EFI_SMM_IO_TRAP_REGISTER_CONTEXT      PchIoTrapContext;
+  EFI_SMM_SX_REGISTER_CONTEXT           SxDispatchContext;
+  SA_IOTRAP_SMI_PROTOCOL                *CpuPcieIoTrapProtocol;
+  EFI_HANDLE                            SxDispatchHandle;
+  UINT8                                 MaxPciePortNum;
+  CPU_PCIE_HOB                          *CpuPcieHob;
+
+  DEBUG ((DEBUG_INFO, "InitializeCpuPcieSmm () Start\n"));
+
+  MaxPciePortNum    = GetMaxCpuPciePortNum ();
+
+  //
+  // Locate Pch Pcie Smi Dispatch Protocol
+  //
+  Status = gSmst->SmmLocateProtocol (&gPchPcieSmiDispatchProtocolGuid, NULL, (VOID**) &PchPcieSmiDispatchProtocol);
+  ASSERT_EFI_ERROR (Status);
+
+  mTempRootPortBusNumMin = PcdGet8 (PcdSiliconInitTempPciBusMin);
+  mTempRootPortBusNumMax = PcdGet8 (PcdSiliconInitTempPciBusMax);
+
+  ///
+  /// Locate HOB for CPU PCIe
+  ///
+  CpuPcieHob = GetFirstGuidHob(&gCpuPcieHobGuid);
+  if (CpuPcieHob != NULL) {
+    ASSERT (sizeof mCpuPcieRootPortConfig == sizeof CpuPcieHob->RootPort);
+    CopyMem (
+      mCpuPcieRootPortConfig,
+      &(CpuPcieHob->RootPort),
+      sizeof (mCpuPcieRootPortConfig)
+      );
+  }
+
+  //
+  // Throught all PCIE root port function and register the SMI Handler for enabled ports.
+  //
+  for (PortIndex = 0; PortIndex < MaxPciePortNum; PortIndex++) {
+    GetCpuPcieRpDevFun (PortIndex, &RpDevice, &RpFunction);
+    RpBase = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, (UINT32) RpDevice, (UINT32) RpFunction, 0);
+    //
+    // Skip the root port function which is not enabled
+    //
+    if (PciSegmentRead32 (RpBase) == 0xFFFFFFFF) {
+      continue;
+    }
+
+    //
+    // Register SMI Handlers for Hot Plug and Link Active State Change
+    //
+    Data8 = PciSegmentRead8 (RpBase + R_PCIE_SLCAP);
+    if (Data8 & B_PCIE_SLCAP_HPC) {
+      PcieHandle = NULL;
+      Status = PchPcieSmiDispatchProtocol->HotPlugRegister (
+                                             PchPcieSmiDispatchProtocol,
+                                             CpuPcieSmiRpHandlerFunction,
+                                             (PortIndex + CpuRpIndex0),
+                                             &PcieHandle
+                                             );
+      ASSERT_EFI_ERROR (Status);
+
+      Status = PchPcieSmiDispatchProtocol->LinkActiveRegister (
+                                             PchPcieSmiDispatchProtocol,
+                                             CpuPcieLinkActiveStateChange,
+                                             (PortIndex + CpuRpIndex0),
+                                             &PcieHandle
+                                             );
+      ASSERT_EFI_ERROR (Status);
+
+      Data32Or  = B_PCIE_MPC_HPME;
+      Data32And = (UINT32) ~B_PCIE_MPC_HPME;
+      S3BootScriptSaveMemReadWrite (
+        S3BootScriptWidthUint32,
+        PcdGet64 (PcdSiPciExpressBaseAddress) + RpBase + R_PCIE_MPC,
+        &Data32Or,  /// Data to be ORed
+        &Data32And  /// Data to be ANDed
+        );
+    }
+
+    //
+    // Register SMI Handler for Link Equalization Request from Gen 3 Devices.
+    //
+    Data8 = PciSegmentRead8 (RpBase + R_PCIE_LCAP);
+    if ((Data8 & B_PCIE_LCAP_MLS) == V_PCIE_LCAP_MLS_GEN3) {
+      Status = PchPcieSmiDispatchProtocol->LinkEqRegister (
+                                             PchPcieSmiDispatchProtocol,
+                                             CpuPcieLinkEqHandlerFunction,
+                                             (PortIndex + CpuRpIndex0),
+                                             &PcieHandle
+                                             );
+      ASSERT_EFI_ERROR (Status);
+    }
+  }
+
+  ASSERT_EFI_ERROR (Status);
+  PchIoTrapContext.Type     = WriteTrap;
+  PchIoTrapContext.Length   = 4;
+  PchIoTrapContext.Address  = 0;
+  Status = mPchIoTrap->Register (
+                         mPchIoTrap,
+                         (EFI_SMM_HANDLER_ENTRY_POINT2) CpuPcieIoTrapSmiCallback,
+                         &PchIoTrapContext,
+                         &PchIoTrapHandle
+                         );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Install the SA Pcie IoTrap protocol
+  //
+  (gBS->AllocatePool) (EfiBootServicesData, sizeof (SA_IOTRAP_SMI_PROTOCOL), (VOID **)&CpuPcieIoTrapProtocol);
+  CpuPcieIoTrapProtocol->SaIotrapSmiAddress = PchIoTrapContext.Address;
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gCpuPcieIoTrapProtocolGuid,
+                  CpuPcieIoTrapProtocol,
+                  NULL
+                  );
+
+  //
+  // Register the callback for S3 entry
+  //
+  SxDispatchContext.Type  = SxS3;
+  SxDispatchContext.Phase = SxEntry;
+  Status = mSxDispatch->Register (
+                          mSxDispatch,
+                          CpuPcieS3EntryCallBack,
+                          &SxDispatchContext,
+                          &SxDispatchHandle
+                          );
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_INFO, "InitializeCpuPcieSmm, IoTrap @ %x () End\n", PchIoTrapContext.Address));
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/SaLateInitSmm.c b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/SaLateInitSmm.c
new file mode 100644
index 0000000000..0e9ba41f1b
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/SaLateInitSmm.c
@@ -0,0 +1,112 @@
+/** @file
+  This SMM driver will handle SA relevant late initialization
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Library/BaseLib.h>
+#include <Base.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/SaPlatformLib.h>
+#include <Protocol/SmmIoTrapDispatch2.h>
+#include "SaLateInitSmm.h"
+#include <Library/PciSegmentLib.h>
+#include <CpuDataStruct.h>
+#include <CpuPcieHob.h>
+#include <Protocol/SaIotrapSmi.h>
+#include <PchPcieRpConfig.h>
+#include <SaConfigHob.h>
+#include "CpuPcieInfo.h"
+#include <Register/CpuPcieRegs.h>
+#include <IndustryStandard/Pci30.h>
+#include <Register/IgdRegs.h>
+#include <Register/CommonMsr.h>
+
+typedef enum {
+  EnumSaSmiCallbackForMaxPayLoad,
+  EnumSaSmiCallbackForSaSaveRestore,
+  EnumSaSmiCallbackForLateInit,
+  EnumSaSmiCallbackForS3resume,
+  EnumSaSmiCallbackMax
+} SMI_OPERATION;
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8                           mSaSmiCallbackPhase      = EnumSaSmiCallbackForMaxPayLoad;
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL        *mPchIoTrap;
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_SMM_SX_DISPATCH2_PROTOCOL             *mSxDispatch;
+
+
+typedef struct {
+  UINT64  BaseAddr;
+  UINT32  Offset;
+  UINT32  AndMask;
+  UINT32  OrMask;
+} BOOT_SCRIPT_REGISTER_SETTING;
+
+/**
+  Initializes the SA SMM handler
+
+  @param[in] ImageHandle - The image handle of Wake On Lan driver
+  @param[in] SystemTable - The standard EFI system table
+
+  @retval EFI_SUCCESS    - SA SMM handler was installed or not necessary
+  @retval EFI_NOT_FOUND  - Fail to register SMI callback or required protocol/hob missing.
+**/
+EFI_STATUS
+EFIAPI
+SaLateInitSmmEntryPoint (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+#if FixedPcdGetBool(PcdCpuPcieEnable) == 1
+  CPU_PCIE_HOB                              *CpuPcieHob = NULL;
+  EFI_STATUS                                Status;
+#endif
+
+  DEBUG ((DEBUG_INFO, "SaLateInitSmmEntryPoint()\n"));
+
+#if FixedPcdGetBool(PcdCpuPcieEnable) == 1
+  CpuPcieHob = (CPU_PCIE_HOB *) GetFirstGuidHob (&gCpuPcieHobGuid);
+  Status = EFI_NOT_FOUND;
+  if (CpuPcieHob == NULL) {
+    DEBUG ((DEBUG_INFO, "CPU PCIE HOB Not found\n"));
+    ASSERT (CpuPcieHob != NULL);
+    return Status;
+  }
+
+  ///
+  /// Locate the PCH Trap dispatch protocol
+  ///
+  Status = gSmst->SmmLocateProtocol (&gEfiSmmIoTrapDispatch2ProtocolGuid, NULL, (VOID **) &mPchIoTrap);
+  ASSERT_EFI_ERROR (Status);
+  Status = gSmst->SmmLocateProtocol (&gEfiSmmSxDispatch2ProtocolGuid, NULL, (VOID**) &mSxDispatch);
+  ASSERT_EFI_ERROR (Status);
+  if (Status == EFI_SUCCESS) {
+    ///
+    /// If ASPM policy is set to "Before OPROM", this SMI callback is not necessary
+    /// Ensure the SMI callback handler will directly return and continue the POST.
+    ///
+    mSaSmiCallbackPhase = EnumSaSmiCallbackMax;
+    Status = EFI_SUCCESS;
+  }
+
+  Status = InitializeCpuPcieSmm (ImageHandle, SystemTable);
+  ASSERT_EFI_ERROR (Status);
+
+  if (Status != EFI_SUCCESS) {
+    DEBUG ((DEBUG_ERROR, "Failed to register SaIotrapSmiCallback!\n"));
+    ///
+    /// System will halt when failing to register required SMI handler
+    ///
+    CpuDeadLoop ();
+  }
+#endif
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/SaLateInitSmm.h b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/SaLateInitSmm.h
new file mode 100644
index 0000000000..c93f92305c
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/SaLateInitSmm.h
@@ -0,0 +1,122 @@
+/** @file
+  Header file for SA SMM Handler
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _SaLateInitSmm_H_
+#define _SaLateInitSmm_H_
+
+///
+/// Driver Consumed Protocol Prototypes
+///
+
+#include <Protocol/SmmBase2.h>
+#include <Protocol/SmmSxDispatch2.h>
+#include <Protocol/SmmIoTrapDispatch2.h>
+#include <Protocol/SaPolicy.h>
+#include <Library/S3BootScriptLib.h>
+#include <CpuPcieConfig.h>
+#include <Library/CpuPcieInfoFruLib.h>
+
+extern EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL        *mPchIoTrap;
+extern EFI_SMM_SX_DISPATCH2_PROTOCOL             *mSxDispatch;
+
+///
+/// The value before AutoConfig match the setting of PCI Express Base Specification 1.1, please be careful for adding new feature
+///
+typedef enum {
+  PcieAspmDisabled,
+  PcieAspmL0s,
+  PcieAspmL1,
+  PcieAspmL0sL1,
+  PcieAspmAutoConfig,
+  PcieAspmMax
+} CPU_PCIE_ASPM_CONFIG;
+
+typedef struct {
+  UINT64                    Address;
+  S3_BOOT_SCRIPT_LIB_WIDTH  Width;
+  UINT32                    Value;
+} BOOT_SCRIPT_PCI_REGISTER_SAVE;
+
+
+/**
+  <b>System Agent Initialization SMM Driver Entry Point</b>
+  - <b>Introduction</b> \n
+    This is an optional driver to support PCIe ASPM initialization later than Option ROM initialization.\n
+    In this scenario S3 Save Boot Script table has been closed per security consideration so the ASPM settings will be stored in SMM memory and restored during S3 resume.
+    If platform does not support this scenario this driver can be excluded and SI_SA_POLICY_PPI -> PCIE_CONFIG -> InitPcieAspmAfterOprom must be set to FALSE. \n
+    Note: When InitPcieAspmAfterOprom enabled, the SMI callback handler must be registered successfully, otherwise it will halt the system.
+
+  - @pre
+    - _EFI_SMM_BASE_PROTOCOL (or _EFI_SMM_BASE2_PROTOCOL for EDK2): Provides SMM infrastructure services.
+    - _EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL (or _EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL for EDK2): Interface structure for the SMM IO trap specific SMI Dispatch Protocol
+    - SA_POLICY_PROTOCOL: A protocol published by a platform DXE module executed earlier; this is documented in this document as well.
+
+  - @result
+    PCIe ASPM has been initialized on all end point devices discovered and same settings will be restored during S3 resume.
+
+  @param[in] ImageHandle - The image handle of Wake On Lan driver
+  @param[in] SystemTable - The standard EFI system table
+
+  @retval EFI_SUCCESS    - SA SMM handler was installed or not necessary
+  @retval EFI_NOT_FOUND  - Fail to register SMI callback or required protocol/hob missing.
+**/
+EFI_STATUS
+EFIAPI
+SaLateInitSmmEntryPoint (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  );
+
+/**
+An IoTrap callback to config PCIE power management settings
+
+@param[in] DispatchHandle  - The handle of this callback, obtained when registering
+@param[in] DispatchContext - Pointer to the EFI_SMM_IO_TRAP_DISPATCH_CALLBACK_CONTEXT
+
+**/
+VOID
+EFIAPI
+CpuPcieIoTrapSmiCallback(
+IN     EFI_HANDLE                     DispatchHandle,
+IN     EFI_SMM_IO_TRAP_CONTEXT        *CallbackContext,
+IN OUT VOID                           *CommBuffer,
+IN OUT UINTN                          *CommBufferSize
+);
+
+/**
+  This function is used to set or clear flags at S3 entry
+  Clear the Io trap executed flag before enter S3
+
+  @param[in] Handle              Handle of the callback
+  @param[in] Context             The dispatch context
+  @param[in,out] CommBuffer      A pointer to a collection of data in memory that will be conveyed from a non-SMM environment into an SMM environment.
+  @param[in,out] CommBufferSize  The size of the CommBuffer.
+  @retval EFI_SUCCESS            SA register saved
+**/
+EFI_STATUS
+EFIAPI
+CpuPcieS3EntryCallBack (
+  IN  EFI_HANDLE                   Handle,
+  IN CONST VOID                    *Context OPTIONAL,
+  IN OUT VOID                      *CommBuffer OPTIONAL,
+  IN OUT UINTN                     *CommBufferSize OPTIONAL
+  );
+
+/**
+  Register PCIE Hotplug SMI dispatch function to handle Hotplug enabling
+
+  @param[in] ImageHandle          The image handle of this module
+  @param[in] SystemTable          The EFI System Table
+
+  @retval EFI_SUCCESS             The function completes successfully
+**/
+EFI_STATUS
+EFIAPI
+InitializeCpuPcieSmm (
+  IN      EFI_HANDLE            ImageHandle,
+  IN      EFI_SYSTEM_TABLE      *SystemTable
+  );
+#endif
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/SaLateInitSmm.inf b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/SaLateInitSmm.inf
new file mode 100644
index 0000000000..ef3486d2a6
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SystemAgent/SaInit/Smm/SaLateInitSmm.inf
@@ -0,0 +1,72 @@
+## @file
+# Component description file for the SA late initialization SMM module.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = SaLateInitSmm
+FILE_GUID = 2D1E361C-7B3F-4d15-8B1F-66E551FABDC7
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_SMM_DRIVER
+PI_SPECIFICATION_VERSION = 1.10
+ENTRY_POINT = SaLateInitSmmEntryPoint
+
+[LibraryClasses]
+UefiDriverEntryPoint
+UefiBootServicesTableLib
+DxeServicesTableLib
+DebugLib
+HobLib
+BaseLib
+S3BootScriptLib
+PciSegmentLib
+SaPlatformLib
+TimerLib
+PciExpressHelpersLib
+PcdLib
+S3BootScriptLib
+CpuPcieInfoFruLib
+ConfigBlockLib
+CpuPcieRpLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+gSiPkgTokenSpaceGuid.PcdSiPciExpressBaseAddress
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempPciBusMax
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempPciBusMin
+gSiPkgTokenSpaceGuid.PcdCpuPcieEnable              ## CONSUMES
+
+
+[Sources]
+SaLateInitSmm.c
+CpuPcieSmm.c
+SaLateInitSmm.h
+
+[Protocols]
+gSaPolicyProtocolGuid              ## CONSUMES
+gEfiSmmIoTrapDispatch2ProtocolGuid ## CONSUMES
+gSaIotrapSmiProtocolGuid           ## PRODUCES
+gCpuPcieIoTrapProtocolGuid         ## PRODUCES
+gEfiSmmSxDispatch2ProtocolGuid     ## CONSUMES
+gPchSmiDispatchProtocolGuid        ## CONSUMES
+gPchPcieSmiDispatchProtocolGuid    ## CONSUMES
+
+[Guids]
+gSaConfigHobGuid
+gCpuPcieHobGuid
+gPcieDxeConfigGuid
+gSaPegHobGuid
+
+[Depex]
+gEfiSmmBase2ProtocolGuid AND
+gEfiSmmSxDispatch2ProtocolGuid AND
+gEfiSmmIoTrapDispatch2ProtocolGuid AND
+gSaPolicyProtocolGuid
+
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 38/40] TigerlakeSiliconPkg/Fru: Add Fru DSC files
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (35 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 37/40] TigerlakeSiliconPkg/SystemAgent: Add SystemAgent modules Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 39/40] TigerlakeSiliconPkg: Add package " Heng Luo
  2021-02-05  7:40 ` [Patch V3 40/40] Maintainers.txt: Add TigerlakeSiliconPkg maintainers Heng Luo
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following DSC files:
  * Fru/TglCpu
  * Fru/TglPch

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/CommonLib.dsc | 11 +++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Dxe.dsc       |  9 +++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/DxeLib.dsc    | 20 ++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Pei.dsc       |  8 ++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/PeiLib.dsc    |  7 +++++++
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/CommonLib.dsc | 30 ++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/Dxe.dsc       |  9 +++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/DxeLib.dsc    | 13 +++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/Pei.dsc       |  8 ++++++++
 Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/PeiLib.dsc    | 10 ++++++++++
 10 files changed, 125 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/CommonLib.dsc b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/CommonLib.dsc
new file mode 100644
index 0000000000..99ee0eccac
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/CommonLib.dsc
@@ -0,0 +1,11 @@
+## @file
+#  Component description file for the TigerLake CPU Common FRU libraries.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+VtdInfoLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Vtd/Library/PeiDxeSmmVtdInfoLib/PeiDxeSmmVtdInfoLib.inf
+CpuPcieRpLib|$(PLATFORM_SI_PACKAGE)/IpBlock/CpuPcieRp/Library/PeiDxeSmmCpuPcieRpLib/PeiDxeSmmCpuPcieRpLib.inf
+CpuPcieInfoFruLib|$(PLATFORM_SI_PACKAGE)/Fru/TglCpu/CpuPcieRp/Library/PeiDxeSmmCpuPcieInfoFruLib/PeiDxeSmmCpuPcieInfoFruLib.inf
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Dxe.dsc b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Dxe.dsc
new file mode 100644
index 0000000000..874e4cbaad
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Dxe.dsc
@@ -0,0 +1,9 @@
+## @file
+#  Component description file for the Tigerlake CPU DXE FRU drivers.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/DxeLib.dsc b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/DxeLib.dsc
new file mode 100644
index 0000000000..5c72c2ac61
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/DxeLib.dsc
@@ -0,0 +1,20 @@
+## @file
+#  Component description file for the Tigerlake CPU DXE FRU libraries.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+DxeGraphicsPolicyLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Graphics/LibraryPrivate/DxeGraphicsPolicyLib/DxeGraphicsPolicyLib.inf
+DxeGraphicsInitLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Graphics/LibraryPrivate/DxeGraphicsInitLib/DxeGraphicsInitLib.inf
+DxeIgdOpRegionInitLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Graphics/LibraryPrivate/DxeIgdOpRegionInitLib/DxeIgdOpRegionInitLib.inf
+DxeVtdInitLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitLib.inf
+DxeVtdPolicyLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyLib/DxeVtdPolicyLib.inf
+DxeVtdInitFruLib|$(PLATFORM_SI_PACKAGE)/Fru/TglCpu/Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitFruLib.inf
+
+
+#
+#  CPU PCIe IpBlock
+#
+DxeCpuPcieRpLib|$(PLATFORM_SI_PACKAGE)/IpBlock/CpuPcieRp/LibraryPrivate/DxeCpuPcieRpLib/DxeCpuPcieRpLib.inf
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Pei.dsc b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Pei.dsc
new file mode 100644
index 0000000000..de8288364a
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/Pei.dsc
@@ -0,0 +1,8 @@
+## @file
+#  Component description file for the Tigerlake CPU PEI FRU drivers.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/PeiLib.dsc b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/PeiLib.dsc
new file mode 100644
index 0000000000..5355ecb288
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglCpu/PeiLib.dsc
@@ -0,0 +1,7 @@
+## @file
+#  Component description file for the Tigerlake CPU PEI FRU ibraries.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/CommonLib.dsc b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/CommonLib.dsc
new file mode 100644
index 0000000000..b7ba1f752c
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/CommonLib.dsc
@@ -0,0 +1,30 @@
+## @file
+#  Component description file for the Tigerlake PCH Common FRU libraries.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+  PsfLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Psf/LibraryPrivate/PsfLib/PeiDxeSmmPsfLibVer2.inf
+  PchPcrLib|$(PLATFORM_SI_PACKAGE)/IpBlock/P2sb/Library/PeiDxeSmmPchPcrLib/PeiDxeSmmPchPcrLib.inf
+  PchSbiAccessLib|$(PLATFORM_SI_PACKAGE)/IpBlock/P2sb/LibraryPrivate/PeiDxeSmmPchSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf
+  GbeMdiLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Gbe/LibraryPrivate/PeiDxeSmmGbeMdiLib/PeiDxeSmmGbeMdiLib.inf
+  GbeLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Gbe/Library/PeiDxeSmmGbeLib/PeiDxeSmmGbeLib.inf
+  EspiLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Espi/Library/PeiDxeSmmEspiLib/PeiDxeSmmEspiLib.inf
+  PmcLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Pmc/Library/PeiDxeSmmPmcLib/PeiDxeSmmPmcLib.inf
+  PmcPrivateLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibVer2.inf
+  PmcPrivateLibWithS3|$(PLATFORM_SI_PACKAGE)/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibWithS3.inf
+  SpiCommonLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Spi/LibraryPrivate/BaseSpiCommonLib/BaseSpiCommonLib.inf
+  GpioLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf
+  GpioPrivateLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibVer2.inf
+  GpioCheckConflictLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Gpio/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLib.inf
+  PchDmiLib|$(PLATFORM_SI_PACKAGE)/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiLib.inf
+  PchDmiWithS3Lib|$(PLATFORM_SI_PACKAGE)/IpBlock/PchDmi/LibraryPrivate/PeiDxeSmmPchDmiLib/PeiDxeSmmPchDmiWithS3Lib.inf
+  SataLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Sata/Library/PeiDxeSmmSataLib/PeiDxeSmmSataLibVer2.inf
+  SpiAccessLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Spi/Library/PeiDxeSmmSpiAccessLib/PeiDxeSmmSpiAccessLib.inf
+  SpiAccessPrivateLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Spi/LibraryPrivate/PeiDxeSmmSpiAccessPrivateLib/PeiDxeSmmSpiAccessPrivateLib.inf
+  PchPcieRpLib|$(PLATFORM_SI_PACKAGE)/IpBlock/PcieRp/Library/PeiDxeSmmPchPcieRpLib/PeiDxeSmmPchPcieRpLibVer2.inf
+  PcieRpLib|$(PLATFORM_SI_PACKAGE)/IpBlock/PcieRp/LibraryPrivate/PcieClientRpLib/PcieClientRpLib.inf
+  PciExpressHelpersLib|$(PLATFORM_SI_PACKAGE)/IpBlock/PcieRp/LibraryPrivate/PciExpressHelpersLibrary/PeiDxeSmmPciExpressHelpersLib.inf
+  BasePcieHelperLib|$(PLATFORM_SI_PACKAGE)/IpBlock/PcieRp/Library/BasePcieHelperLib/BasePcieHelperLib.inf
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/Dxe.dsc b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/Dxe.dsc
new file mode 100644
index 0000000000..9fefc6b4c9
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/Dxe.dsc
@@ -0,0 +1,9 @@
+## @file
+#  Component description file for the Tigerlake PCH DXE FRU drivers.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+$(PLATFORM_SI_PACKAGE)/IpBlock/Spi/Smm/SpiSmm.inf
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/DxeLib.dsc b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/DxeLib.dsc
new file mode 100644
index 0000000000..e9be448baa
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/DxeLib.dsc
@@ -0,0 +1,13 @@
+## @file
+#  Component description file for the Tigerlake PCH DXE FRU libraries.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+  DxeHdaNhltLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Hda/Library/DxeHdaNhltLib/DxeHdaNhltLib.inf
+  DxeHdaPolicyLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Hda/LibraryPrivate/DxeHdaPolicyLib/DxeHdaPolicyLib.inf
+  GpioHelpersLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf
+  GpioNameBufferLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Gpio/LibraryPrivate/DxeGpioNameBufferLib/DxeGpioNameBufferLib.inf
+  DxeGpioPolicyLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Gpio/LibraryPrivate/DxeGpioPolicyLib/DxeGpioPolicyLib.inf
+  DxePchPcieRpPolicyLib|$(PLATFORM_SI_PACKAGE)/IpBlock/PcieRp/LibraryPrivate/DxePchPcieRpPolicyLib/DxePchPcieRpPolicyLib.inf
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/Pei.dsc b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/Pei.dsc
new file mode 100644
index 0000000000..2eacbe905c
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/Pei.dsc
@@ -0,0 +1,8 @@
+## @file
+#  Component description file for the Tigerlake PCH PEI FRU drivers.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/PeiLib.dsc b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/PeiLib.dsc
new file mode 100644
index 0000000000..d8e6313084
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/Fru/TglPch/PeiLib.dsc
@@ -0,0 +1,10 @@
+## @file
+#  Component description file for the Tigerlake PCH PEI FRU libraries.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+  GpioHelpersLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.inf
+  GpioNameBufferLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Gpio/LibraryPrivate/PeiGpioNameBufferLib/PeiGpioNameBufferLib.inf
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 39/40] TigerlakeSiliconPkg: Add package DSC files
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (36 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 38/40] TigerlakeSiliconPkg/Fru: Add Fru DSC files Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05  7:40 ` [Patch V3 40/40] Maintainers.txt: Add TigerlakeSiliconPkg maintainers Heng Luo
  38 siblings, 0 replies; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/SiPkgBuildOption.dsc    | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SiPkgCommonLib.dsc      |  43 +++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SiPkgDxe.dsc            |  47 +++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SiPkgDxeLib.dsc         |  40 ++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SiPkgPei.dsc            |  20 ++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/SiPkgPeiLib.dsc         |  20 ++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/TigerlakeSiliconPkg.dsc | 229 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 521 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SiPkgBuildOption.dsc b/Silicon/Intel/TigerlakeSiliconPkg/SiPkgBuildOption.dsc
new file mode 100644
index 0000000000..51c40812ea
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SiPkgBuildOption.dsc
@@ -0,0 +1,122 @@
+## @file
+#  Silicon build option configuration file.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[BuildOptions]
+# Define Build Options both for EDK and EDKII drivers.
+
+  DEFINE PCH_BUILD_OPTIONS = -DPCH_TGL
+#
+# SA
+#
+!if gSiPkgTokenSpaceGuid.PcdBdatEnable == TRUE
+  DEFINE BDAT_BUILD_OPTION = -DBDAT_SUPPORT=1
+!else
+  DEFINE BDAT_BUILD_OPTION =
+!endif
+
+  DEFINE SLE_BUILD_OPTIONS =
+!if $(TARGET) == RELEASE
+!if gSiPkgTokenSpaceGuid.PcdSiCatalogDebugEnable == TRUE
+  DEFINE DEBUG_BUILD_OPTIONS =
+!else
+  # MDEPKG_NDEBUG is introduced for the intention
+  # of size reduction when compiler optimization is disabled. If MDEPKG_NDEBUG is
+  # defined, then debug and assert related macros wrapped by it are the NULL implementations.
+  DEFINE DEBUG_BUILD_OPTIONS = -DMDEPKG_NDEBUG
+!endif
+!else
+  DEFINE DEBUG_BUILD_OPTIONS =
+!endif
+
+!if ($(TARGET) == RELEASE) AND (gSiPkgTokenSpaceGuid.PcdSiCatalogDebugEnable == TRUE)
+  DEFINE RELEASE_CATALOG_BUILD_OPTIONS = -DRELEASE_CATALOG
+!else
+  DEFINE RELEASE_CATALOG_BUILD_OPTIONS =
+!endif
+
+!if gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable == FALSE
+  DEFINE OPTIMIZE_DISABLE_OPTIONS = -Od -GL-
+!else
+  DEFINE OPTIMIZE_DISABLE_OPTIONS =
+!endif
+
+  DEFINE HSLE_BUILD_OPTIONS =
+
+
+  DEFINE CPU_FLAGS = -DCPU_ICL -DCPU_TGL
+
+
+  DEFINE RESTRICTED_OPTION =
+
+!if gSiPkgTokenSpaceGuid.PcdMrcTraceMessageSupported == FALSE
+  *_*_*_MRC_NDEBUG = -DMDEPKG_NDEBUG
+!endif
+
+DEFINE DSC_SIPKG_FEATURE_BUILD_OPTIONS = $(BDAT_BUILD_OPTION) $(DEBUG_BUILD_OPTIONS)
+DEFINE DSC_SIPKG_FEATURE_BUILD_OPTIONS = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS) $(PCH_BUILD_OPTIONS) $(CPU_FLAGS) $(HSLE_BUILD_OPTIONS)
+
+!if gSiPkgTokenSpaceGuid.PcdSourceDebugEnable == TRUE
+  *_*_X64_GENFW_FLAGS = --keepexceptiontable
+!endif
+
+[BuildOptions.Common.EDKII]
+
+#
+# For IA32 Global Build Flag
+#
+       *_*_IA32_CC_FLAGS      = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS) -D PI_SPECIFICATION_VERSION=0x00010015 -DASF_PEI
+       *_*_IA32_VFRPP_FLAGS   = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS)
+       *_*_IA32_APP_FLAGS     = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS)
+       *_*_IA32_ASLPP_FLAGS   = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS)
+       *_*_IA32_ASLCC_FLAGS   = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS)
+
+#
+# For IA32 Specific Build Flag
+#
+GCC:   *_*_IA32_PP_FLAGS      = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS)
+MSFT:  *_*_IA32_ASM_FLAGS     = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS)
+MSFT:  *_*_IA32_CC_FLAGS      = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS) -D PI_SPECIFICATION_VERSION=0x00010015 -DASF_PEI /w34668
+MSFT:  *_*_IA32_VFRPP_FLAGS   = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
+MSFT:  *_*_IA32_APP_FLAGS     = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
+MSFT:  *_*_IA32_ASLPP_FLAGS   = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
+MSFT:  *_*_IA32_ASLCC_FLAGS   = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
+
+#
+# For X64 Global Build Flag
+#
+       *_*_X64_CC_FLAGS       = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS) -D PI_SPECIFICATION_VERSION=0x00010015
+       *_*_X64_VFRPP_FLAGS    = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS)
+       *_*_X64_APP_FLAGS      = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS)
+       *_*_X64_ASLPP_FLAGS    = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS)
+       *_*_X64_ASLCC_FLAGS    = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS)
+
+#
+# For X64 Specific Build Flag
+#
+GCC:   *_*_X64_PP_FLAGS       = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS)
+MSFT:  *_*_X64_ASM_FLAGS      = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS)
+MSFT:  *_*_X64_CC_FLAGS       = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS) -D PI_SPECIFICATION_VERSION=0x00010015 /w34668
+MSFT:  *_*_X64_VFRPP_FLAGS    = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
+MSFT:  *_*_X64_APP_FLAGS      = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS) $(OPTIMIZE_DISABLE_OPTIONS)
+MSFT:  *_*_X64_ASLPP_FLAGS    = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS)
+MSFT:  *_*_X64_ASLCC_FLAGS    = $(DSC_SIPKG_FEATURE_BUILD_OPTIONS)
+
+#
+# For Xcode Specific Build Flag
+#
+# Override assembly code build order
+*_XCODE5_*_*_BUILDRULEORDER = nasm S s
+# Align 47bfbd7f8069e523798ef973c8eb0abd5c6b0746 to fix the usage of VA_START in undefined way
+*_XCODE5_*_CC_FLAGS = -Wno-varargs
+
+# Force PE/COFF sections to be aligned at 4KB boundaries to support page level protection of runtime modules
+[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
+  MSFT:  *_*_*_DLINK_FLAGS      = /ALIGN:4096
+  GCC:   *_GCC*_*_DLINK_FLAGS   = -z common-page-size=0x1000
+
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SiPkgCommonLib.dsc b/Silicon/Intel/TigerlakeSiliconPkg/SiPkgCommonLib.dsc
new file mode 100644
index 0000000000..16f148f1e7
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SiPkgCommonLib.dsc
@@ -0,0 +1,43 @@
+## @file
+#  Component description file for the TigerLake silicon package both Pei and Dxe libraries DSC file.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+#
+# FRUs
+#
+!include $(PLATFORM_SI_PACKAGE)/Fru/TglCpu/CommonLib.dsc
+!include $(PLATFORM_SI_PACKAGE)/Fru/TglPch/CommonLib.dsc
+
+#
+# Common
+#
+ MmPciLib|$(PLATFORM_SI_PACKAGE)/Library/PeiDxeSmmMmPciLib/PeiDxeSmmMmPciLib.inf
+ PciSegmentLib|$(PLATFORM_SI_PACKAGE)/Library/BasePciSegmentMultiSegLibPci/BasePciSegmentMultiSegLibPci.inf
+
+#
+# Pch
+#
+ PchCycleDecodingLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchCycleDecodingLib/PeiDxeSmmPchCycleDecodingLib.inf
+ PchInfoLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchInfoLib/PeiDxeSmmPchInfoLibTgl.inf
+ CpuPcieInitCommonLib|$(PLATFORM_SI_PACKAGE)/IpBlock/CpuPcieRp/Library/PeiDxeSmmCpuPcieInitCommonLib/PeiDxeSmmCpuPcieInitCommonLib.inf
+ CpuPcieRpLib|$(PLATFORM_SI_PACKAGE)/IpBlock/CpuPcieRp/Library/PeiDxeSmmCpuPcieRpLib/PeiDxeSmmCpuPcieRpLib.inf
+
+ SerialIoAccessLib|$(PLATFORM_SI_PACKAGE)/IpBlock/SerialIo/Library/PeiDxeSmmSerialIoAccessLib/PeiDxeSmmSerialIoAccessLib.inf
+ SerialIoPrivateLib|$(PLATFORM_SI_PACKAGE)/IpBlock/SerialIo/LibraryPrivate/PeiDxeSmmSerialIoPrivateLib/PeiDxeSmmSerialIoPrivateLibVer2.inf
+ ResetSystemLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.inf
+ #private
+ GpioPrivateLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibVer2.inf
+
+ SiScheduleResetLib|$(PLATFORM_SI_PACKAGE)/Pch/LibraryPrivate/BaseSiScheduleResetLib/BaseSiScheduleResetLib.inf
+ PchPciBdfLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/BasePchPciBdfLib/BasePchPciBdfLib.inf
+ PcieRpLib|$(PLATFORM_SI_PACKAGE)/IpBlock/PcieRp/LibraryPrivate/PcieClientRpLib/PcieClientRpLib.inf
+
+#
+# SA
+#
+ SaPlatformLib|$(PLATFORM_SI_PACKAGE)/SystemAgent/Library/PeiDxeSmmSaPlatformLib/PeiDxeSmmSaPlatformLib.inf
+ CpuRegbarAccessLib|$(PLATFORM_SI_PACKAGE)/IpBlock/P2sb/Library/PeiDxeSmmCpuRegbarAccessLib/PeiDxeSmmCpuRegbarAccessLib.inf
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SiPkgDxe.dsc b/Silicon/Intel/TigerlakeSiliconPkg/SiPkgDxe.dsc
new file mode 100644
index 0000000000..1a08fbc24c
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SiPkgDxe.dsc
@@ -0,0 +1,47 @@
+## @file
+#  Component description file for the TigerLake silicon package DXE drivers.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+#
+# FRUs
+#
+!include $(PLATFORM_SI_PACKAGE)/Fru/TglCpu/Dxe.dsc
+!include $(PLATFORM_SI_PACKAGE)/Fru/TglPch/Dxe.dsc
+
+#
+# Common
+#
+
+#
+# Pch
+#
+  $(PLATFORM_SI_PACKAGE)/Pch/PchInit/Dxe/PchInitDxeTgl.inf
+  $(PLATFORM_SI_PACKAGE)/Pch/SmmControl/RuntimeDxe/SmmControl.inf
+
+  $(PLATFORM_SI_PACKAGE)/Pch/PchSmiDispatcher/Smm/PchSmiDispatcher.inf{
+    <LibraryClasses>
+      #SmiHandlerProfileLib|MdeModulePkg/Library/SmmSmiHandlerProfileLib/SmmSmiHandlerProfileLib.inf
+      SmiHandlerProfileLib|MdePkg/Library/SmiHandlerProfileLibNull/SmiHandlerProfileLibNull.inf
+  }
+  $(PLATFORM_SI_PACKAGE)/Pch/PchInit/Smm/PchInitSmm.inf
+
+#
+# SystemAgent
+#
+
+  $(PLATFORM_SI_PACKAGE)/SystemAgent/SaInit/Dxe/SaInitDxe.inf
+
+  $(PLATFORM_SI_PACKAGE)/SystemAgent/SaInit/Smm/SaLateInitSmm.inf {
+    <LibraryClasses>
+      S3BootScriptLib|MdePkg/Library/BaseS3BootScriptLibNull/BaseS3BootScriptLibNull.inf
+  }
+
+!if gSiPkgTokenSpaceGuid.PcdAcpiEnable == TRUE
+  $(PLATFORM_SI_PACKAGE)/SystemAgent/AcpiTables/SaSsdt/SaSsdt.inf
+  $(PLATFORM_SI_PACKAGE)/IpBlock/Graphics/AcpiTables/IgfxSsdt.inf
+!endif
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SiPkgDxeLib.dsc b/Silicon/Intel/TigerlakeSiliconPkg/SiPkgDxeLib.dsc
new file mode 100644
index 0000000000..210fb37332
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SiPkgDxeLib.dsc
@@ -0,0 +1,40 @@
+## @file
+#  Component description file for the TigerLake silicon package DXE libraries.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+#
+# Silicon Init Dxe Library
+#
+
+#
+# FRUs
+#
+!include $(PLATFORM_SI_PACKAGE)/Fru/TglCpu/DxeLib.dsc
+!include $(PLATFORM_SI_PACKAGE)/Fru/TglPch/DxeLib.dsc
+
+#
+# Common
+#
+SiConfigBlockLib|$(PLATFORM_SI_PACKAGE)/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf
+
+#
+# Pch
+#
+DxePchPolicyLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/DxePchPolicyLib/DxePchPolicyLib.inf
+SmmPchPrivateLib|$(PLATFORM_SI_PACKAGE)/Pch/LibraryPrivate/SmmPchPrivateLib/SmmPchPrivateLib.inf
+
+#
+# SystemAgent
+#
+DxeSaPolicyLib|$(PLATFORM_SI_PACKAGE)/SystemAgent/Library/DxeSaPolicyLib/DxeSaPolicyLib.inf
+DxeVtdPolicyLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyLib/DxeVtdPolicyLib.inf
+
+#
+#  CPU PCIe IpBlock
+#
+
+DxeCpuPcieRpLib|$(PLATFORM_SI_PACKAGE)/IpBlock/CpuPcieRp/LibraryPrivate/DxeCpuPcieRpLib/DxeCpuPcieRpLib.inf
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SiPkgPei.dsc b/Silicon/Intel/TigerlakeSiliconPkg/SiPkgPei.dsc
new file mode 100644
index 0000000000..15fc5685a5
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SiPkgPei.dsc
@@ -0,0 +1,20 @@
+## @file
+#  Component description file for the TigerLake silicon package PEI drivers.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+#
+# Common
+#
+
+#
+# SystemAgent
+#
+
+#
+# Cpu
+#
+
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/SiPkgPeiLib.dsc b/Silicon/Intel/TigerlakeSiliconPkg/SiPkgPeiLib.dsc
new file mode 100644
index 0000000000..6f90ff02bb
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/SiPkgPeiLib.dsc
@@ -0,0 +1,20 @@
+## @file
+#  Component description file for the TigerLake silicon package PEI libraries.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+#
+# Silicon Init Pei Library
+#
+
+#
+# FRUs
+#
+!include $(PLATFORM_SI_PACKAGE)/Fru/TglCpu/PeiLib.dsc
+
+!include $(PLATFORM_SI_PACKAGE)/Fru/TglPch/PeiLib.dsc
+
+ SiConfigBlockLib|$(PLATFORM_SI_PACKAGE)/Library/BaseSiConfigBlockLib/BaseSiConfigBlockLib.inf
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/TigerlakeSiliconPkg.dsc b/Silicon/Intel/TigerlakeSiliconPkg/TigerlakeSiliconPkg.dsc
new file mode 100644
index 0000000000..73a2594887
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/TigerlakeSiliconPkg.dsc
@@ -0,0 +1,229 @@
+## @file
+#  Component description file for the TigerLake silicon package DSC file.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+[Packages]
+MdePkg/MdePkg.dec
+UefiCpuPkg/UefiCpuPkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+[PcdsFixedAtBuild]
+gSiPkgTokenSpaceGuid.PcdSmmVariableEnable            |TRUE
+gSiPkgTokenSpaceGuid.PcdAtaEnable                    |FALSE
+
+gSiPkgTokenSpaceGuid.PcdAcpiEnable                   |TRUE
+gSiPkgTokenSpaceGuid.PcdSourceDebugEnable            |FALSE
+gSiPkgTokenSpaceGuid.PcdPpmEnable                    |TRUE
+gSiPkgTokenSpaceGuid.PcdPttEnable                    |FALSE
+gSiPkgTokenSpaceGuid.PcdJhiEnable                    |FALSE
+gSiPkgTokenSpaceGuid.PcdSmbiosEnable                 |TRUE
+gSiPkgTokenSpaceGuid.PcdS3Enable                     |TRUE
+gSiPkgTokenSpaceGuid.PcdOverclockEnable              |FALSE
+gSiPkgTokenSpaceGuid.PcdCpuPowerOnConfigEnable       |FALSE
+gSiPkgTokenSpaceGuid.PcdBdatEnable                   |TRUE
+gSiPkgTokenSpaceGuid.PcdIgdEnable                    |TRUE
+gSiPkgTokenSpaceGuid.PcdPegEnable                    |TRUE
+gSiPkgTokenSpaceGuid.PcdSaDmiEnable                  |TRUE
+gSiPkgTokenSpaceGuid.PcdVtdEnable                    |TRUE
+gSiPkgTokenSpaceGuid.PcdBiosGuardEnable              |FALSE  #BiosGuardModule.bin
+gSiPkgTokenSpaceGuid.PcdOptimizeCompilerEnable       |TRUE
+gSiPkgTokenSpaceGuid.PcdPeiDisplayEnable             |TRUE
+gSiPkgTokenSpaceGuid.PcdSiCatalogDebugEnable         |FALSE
+gSiPkgTokenSpaceGuid.PcdMrcTraceMessageSupported     |TRUE
+gSiPkgTokenSpaceGuid.PcdOcWdtEnable                  |TRUE
+gSiPkgTokenSpaceGuid.PcdSerialIoUartEnable           |TRUE
+
+gSiPkgTokenSpaceGuid.PcdThcEnable                    |TRUE
+gSiPkgTokenSpaceGuid.PcdPpamEnable                   |TRUE
+gSiPkgTokenSpaceGuid.PcdEmbeddedEnable               |0x0
+gSiPkgTokenSpaceGuid.PcdCpuPcieEnable                |TRUE
+gSiPkgTokenSpaceGuid.PcdHybridStorageSupport         |TRUE
+
+!if gSiPkgTokenSpaceGuid.PcdPpamEnable == TRUE
+#
+# PCD for State Save Support on DGR
+# TRUE - SMM State Save region access is protected
+# FALSE - SMM can have Read/Write access to SMM State Save region
+#
+gSiPkgTokenSpaceGuid.PcdSpsStateSaveEnable           |FALSE
+#
+# PCD to enable SPA Support on DGR
+# Note: This PCD is mainly used for Debugging purpose. Not recommended to set for End Product.
+#
+gSiPkgTokenSpaceGuid.PcdSpaEnable                    |FALSE
+!endif
+
+[PcdsFixedAtBuild.common]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress       |0xC0000000
+gSiPkgTokenSpaceGuid.PcdSiPciExpressBaseAddress         |gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+gSiPkgTokenSpaceGuid.PcdTemporaryPciExpressRegionLength |0x10000000
+
+[PcdsDynamicDefault.common]
+gSiPkgTokenSpaceGuid.PcdPciExpressRegionLength          |0x10000000
+## Specifies the AP wait loop state during POST phase.
+#  The value is defined as below.
+#  1: Place AP in the Hlt-Loop state.
+#  2: Place AP in the Mwait-Loop state.
+#  3: Place AP in the Run-Loop state.
+# @Prompt The AP wait loop state.
+gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode|2
+## Specifies the AP target C-state for Mwait during POST phase.
+#  The default value 0 means C1 state.
+#  The value is defined as below.<BR><BR>
+# @Prompt The specified AP target C-state for Mwait.
+gUefiCpuPkgTokenSpaceGuid.PcdCpuApTargetCstate|0
+
+[Defines]
+  PLATFORM_NAME = TigerlakeSiliconPkg
+  PLATFORM_GUID = CCD38CA7-61D3-4185-9CDA-A9FDF209CB31
+  PLATFORM_VERSION = 0.4
+  DSC_SPECIFICATION = 0x00010005
+  OUTPUT_DIRECTORY = Build/TigerlakeSiliconPkg
+  SUPPORTED_ARCHITECTURES = IA32|X64
+  BUILD_TARGETS = DEBUG|RELEASE
+  SKUID_IDENTIFIER = DEFAULT
+
+  DEFINE   PLATFORM_SI_PACKAGE        = TigerlakeSiliconPkg
+  #
+  # Definition for Build Flag
+  #
+  !include $(PLATFORM_SI_PACKAGE)/SiPkgBuildOption.dsc
+
+[LibraryClasses.common]
+  #
+  # Entry point
+  #
+  PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
+  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+  PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+
+  #
+  # Basic
+  #
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+  PciSegmentLib|$(PLATFORM_SI_PACKAGE)/Library/BasePciSegmentMultiSegLibPci/BasePciSegmentMultiSegLibPci.inf
+  PciLib|MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf
+  PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
+  CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+  PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
+  PostCodeLib|MdePkg/Library/BasePostCodeLibPort80/BasePostCodeLibPort80.inf
+
+  #
+  # UEFI & PI
+  #
+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+  PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+
+  S3BootScriptLib|MdePkg/Library/BaseS3BootScriptLibNull/BaseS3BootScriptLibNull.inf
+  S3IoLib|MdePkg/Library/BaseS3IoLib/BaseS3IoLib.inf
+  S3PciLib|MdePkg/Library/BaseS3PciLib/BaseS3PciLib.inf
+
+  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
+  SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+
+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+
+  #
+  # Misc
+  #
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
+  ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
+  MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf
+  RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf
+
+#####################################################################################################
+
+#
+# Silicon Init Common Library
+#
+!include $(PLATFORM_SI_PACKAGE)/SiPkgCommonLib.dsc
+ConfigBlockLib|IntelSiliconPkg/Library/BaseConfigBlockLib/BaseConfigBlockLib.inf
+
+[LibraryClasses.IA32]
+#
+# PEI phase common
+#
+  PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
+  PeiGetVtdPmrAlignmentLib|IntelSiliconPkg/Library/PeiGetVtdPmrAlignmentLib/PeiGetVtdPmrAlignmentLib.inf
+
+#####################################################################################################################################
+
+#
+# Silicon Init Pei Library
+#
+!include $(PLATFORM_SI_PACKAGE)/SiPkgPeiLib.dsc
+
+[LibraryClasses.IA32.SEC]
+  GpioHelpersLib|$(PLATFORM_SI_PACKAGE)/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf
+
+[LibraryClasses.X64]
+ #
+ # DXE phase common
+ #
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+
+#
+# Hsti
+#
+  HstiLib|MdePkg/Library/DxeHstiLib/DxeHstiLib.inf
+
+###################################################################################################
+#
+# Silicon Init Dxe Library
+#
+!include $(PLATFORM_SI_PACKAGE)/SiPkgDxeLib.dsc
+
+[LibraryClasses.X64.PEIM]
+
+[LibraryClasses.X64.DXE_CORE]
+  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+
+[LibraryClasses.X64.DXE_SMM_DRIVER]
+  SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf
+  MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf
+  SmmIoLib|MdePkg/Library/SmmIoLib/SmmIoLib.inf
+  SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf
+
+[LibraryClasses.X64.SMM_CORE]
+
+[LibraryClasses.X64.UEFI_DRIVER]
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+
+[LibraryClasses.X64.UEFI_APPLICATION]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+
+[Components.IA32]
+!include $(PLATFORM_SI_PACKAGE)/SiPkgPei.dsc
+
+[Components.X64]
+!include $(PLATFORM_SI_PACKAGE)/SiPkgDxe.dsc
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Patch V3 40/40] Maintainers.txt: Add TigerlakeSiliconPkg maintainers
  2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
                   ` (37 preceding siblings ...)
  2021-02-05  7:40 ` [Patch V3 39/40] TigerlakeSiliconPkg: Add package " Heng Luo
@ 2021-02-05  7:40 ` Heng Luo
  2021-02-05 18:36   ` Nate DeSimone
  38 siblings, 1 reply; 42+ messages in thread
From: Heng Luo @ 2021-02-05  7:40 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Nate DeSimone

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Heng Luo <heng.luo@intel.com>
---
 Maintainers.txt | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Maintainers.txt b/Maintainers.txt
index 56e16fc48c..34f0b58581 100644
--- a/Maintainers.txt
+++ b/Maintainers.txt
@@ -242,6 +242,12 @@ F: Silicon/Intel/KabylakeSiliconPkg/
 M: Chasel Chiu <chasel.chiu@intel.com>
 M: Sai Chaganty <rangasai.v.chaganty@intel.com>
 
+Silicon/Intel/TigerlakeSiliconPkg
+F: Silicon/Intel/TigerlakeSiliconPkg/
+M: Sai Chaganty <rangasai.v.chaganty@intel.com>
+M: Nate DeSimone <nathaniel.l.desimone@intel.com>
+R: Heng Luo <heng.luo@intel.com>
+
 Silicon/Intel/SimicsX58SktPkg
 F: Silicon/Intel/SimicsX58SktPkg/
 M: Agyeman Prince <prince.agyeman@intel.com>
-- 
2.24.0.windows.2


^ permalink raw reply related	[flat|nested] 42+ messages in thread

* Re: [Patch V3 40/40] Maintainers.txt: Add TigerlakeSiliconPkg maintainers
  2021-02-05  7:40 ` [Patch V3 40/40] Maintainers.txt: Add TigerlakeSiliconPkg maintainers Heng Luo
@ 2021-02-05 18:36   ` Nate DeSimone
  2021-02-05 18:57     ` Chaganty, Rangasai V
  0 siblings, 1 reply; 42+ messages in thread
From: Nate DeSimone @ 2021-02-05 18:36 UTC (permalink / raw)
  To: Luo, Heng, devel@edk2.groups.io; +Cc: Chaganty, Rangasai V

The series has been pushed as d55602c~..ee33d4f

Thanks Again Heng!

> -----Original Message-----
> From: Luo, Heng <heng.luo@intel.com>
> Sent: Thursday, February 4, 2021 11:41 PM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Desimone,
> Nathaniel L <nathaniel.l.desimone@intel.com>
> Subject: [Patch V3 40/40] Maintainers.txt: Add TigerlakeSiliconPkg
> maintainers
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Signed-off-by: Heng Luo <heng.luo@intel.com>
> ---
>  Maintainers.txt | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Maintainers.txt b/Maintainers.txt index 56e16fc48c..34f0b58581
> 100644
> --- a/Maintainers.txt
> +++ b/Maintainers.txt
> @@ -242,6 +242,12 @@ F: Silicon/Intel/KabylakeSiliconPkg/
>  M: Chasel Chiu <chasel.chiu@intel.com> M: Sai Chaganty
> <rangasai.v.chaganty@intel.com> +Silicon/Intel/TigerlakeSiliconPkg+F:
> Silicon/Intel/TigerlakeSiliconPkg/+M: Sai Chaganty
> <rangasai.v.chaganty@intel.com>+M: Nate DeSimone
> <nathaniel.l.desimone@intel.com>+R: Heng Luo <heng.luo@intel.com>+
> Silicon/Intel/SimicsX58SktPkg F: Silicon/Intel/SimicsX58SktPkg/ M: Agyeman
> Prince <prince.agyeman@intel.com>--
> 2.24.0.windows.2


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Patch V3 40/40] Maintainers.txt: Add TigerlakeSiliconPkg maintainers
  2021-02-05 18:36   ` Nate DeSimone
@ 2021-02-05 18:57     ` Chaganty, Rangasai V
  0 siblings, 0 replies; 42+ messages in thread
From: Chaganty, Rangasai V @ 2021-02-05 18:57 UTC (permalink / raw)
  To: Desimone, Nathaniel L, Luo, Heng, devel@edk2.groups.io

Thanks Heng for all the hard work! And thank you Nate for pushing the series.

-----Original Message-----
From: Desimone, Nathaniel L <nathaniel.l.desimone@intel.com> 
Sent: Friday, February 05, 2021 10:37 AM
To: Luo, Heng <heng.luo@intel.com>; devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>
Subject: RE: [Patch V3 40/40] Maintainers.txt: Add TigerlakeSiliconPkg maintainers

The series has been pushed as d55602c~..ee33d4f

Thanks Again Heng!

> -----Original Message-----
> From: Luo, Heng <heng.luo@intel.com>
> Sent: Thursday, February 4, 2021 11:41 PM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Desimone, 
> Nathaniel L <nathaniel.l.desimone@intel.com>
> Subject: [Patch V3 40/40] Maintainers.txt: Add TigerlakeSiliconPkg 
> maintainers
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Signed-off-by: Heng Luo <heng.luo@intel.com>
> ---
>  Maintainers.txt | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Maintainers.txt b/Maintainers.txt index 
> 56e16fc48c..34f0b58581
> 100644
> --- a/Maintainers.txt
> +++ b/Maintainers.txt
> @@ -242,6 +242,12 @@ F: Silicon/Intel/KabylakeSiliconPkg/
>  M: Chasel Chiu <chasel.chiu@intel.com> M: Sai Chaganty 
> <rangasai.v.chaganty@intel.com> +Silicon/Intel/TigerlakeSiliconPkg+F:
> Silicon/Intel/TigerlakeSiliconPkg/+M: Sai Chaganty
> <rangasai.v.chaganty@intel.com>+M: Nate DeSimone
> <nathaniel.l.desimone@intel.com>+R: Heng Luo <heng.luo@intel.com>+ 
> Silicon/Intel/SimicsX58SktPkg F: Silicon/Intel/SimicsX58SktPkg/ M: 
> Agyeman Prince <prince.agyeman@intel.com>--
> 2.24.0.windows.2


^ permalink raw reply	[flat|nested] 42+ messages in thread

end of thread, other threads:[~2021-02-05 18:57 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-02-05  7:40 [Patch V3 01/40] TigerlakeSiliconPkg: Add package and Include/ConfigBlock headers Heng Luo
2021-02-05  7:40 ` [Patch V3 02/40] TigerlakeSiliconPkg/Include: Add Library, PPI and Protocol include headers Heng Luo
2021-02-05  7:40 ` [Patch V3 03/40] TigerlakeSiliconPkg/Include: Add Pins, Register and other " Heng Luo
2021-02-05  7:40 ` [Patch V3 04/40] TigerlakeSiliconPkg/Cpu: Add Include headers Heng Luo
2021-02-05  7:40 ` [Patch V3 05/40] TigerlakeSiliconPkg/Pch: Add include headers Heng Luo
2021-02-05  7:40 ` [Patch V3 06/40] TigerlakeSiliconPkg/Pch: Add IncludePrivate headers Heng Luo
2021-02-05  7:40 ` [Patch V3 07/40] TigerlakeSiliconPkg/SystemAgent: Add include headers Heng Luo
2021-02-05  7:40 ` [Patch V3 08/40] TigerlakeSiliconPkg/SystemAgent: Add IncludePrivate headers Heng Luo
2021-02-05  7:40 ` [Patch V3 09/40] TigerlakeSiliconPkg/Fru: Add TglCpu/Include headers Heng Luo
2021-02-05  7:40 ` [Patch V3 10/40] TigerlakeSiliconPkg/Fru: Add TglCpu/IncludePrivate headers Heng Luo
2021-02-05  7:40 ` [Patch V3 11/40] TigerlakeSiliconPkg/Fru: Add TglPch/Include headers Heng Luo
2021-02-05  7:40 ` [Patch V3 12/40] TigerlakeSiliconPkg/Fru: Add TglPch/IncludePrivate headers Heng Luo
2021-02-05  7:40 ` [Patch V3 13/40] TigerlakeSiliconPkg/IpBlock: Add Cnvi component Heng Luo
2021-02-05  7:40 ` [Patch V3 14/40] TigerlakeSiliconPkg/IpBlock: Add CpuPcieRp component Heng Luo
2021-02-05  7:40 ` [Patch V3 15/40] TigerlakeSiliconPkg/IpBlock: Add Espi component Heng Luo
2021-02-05  7:40 ` [Patch V3 16/40] TigerlakeSiliconPkg/IpBlock: Add Gbe component Heng Luo
2021-02-05  7:40 ` [Patch V3 17/40] TigerlakeSiliconPkg/IpBlock: Add Gpio component Heng Luo
2021-02-05  7:40 ` [Patch V3 18/40] TigerlakeSiliconPkg/IpBlock: Add Graphics component Heng Luo
2021-02-05  7:40 ` [Patch V3 19/40] TigerlakeSiliconPkg/IpBlock: Add Hda component Heng Luo
2021-02-05  7:40 ` [Patch V3 20/40] TigerlakeSiliconPkg/IpBlock: Add HostBridge component Heng Luo
2021-02-05  7:40 ` [Patch V3 21/40] TigerlakeSiliconPkg/IpBlock: Add P2sb component Heng Luo
2021-02-05  7:40 ` [Patch V3 22/40] TigerlakeSiliconPkg/IpBlock: Add PchDmi component Heng Luo
2021-02-05  7:40 ` [Patch V3 23/40] TigerlakeSiliconPkg/IpBlock: Add PcieRp component Heng Luo
2021-02-05  7:40 ` [Patch V3 24/40] TigerlakeSiliconPkg/IpBlock: Add Pmc component Heng Luo
2021-02-05  7:40 ` [Patch V3 25/40] TigerlakeSiliconPkg/IpBlock: Add Psf component Heng Luo
2021-02-05  7:40 ` [Patch V3 26/40] TigerlakeSiliconPkg/IpBlock: Add Sata component Heng Luo
2021-02-05  7:40 ` [Patch V3 27/40] TigerlakeSiliconPkg/IpBlock: Add SerialIo component Heng Luo
2021-02-05  7:40 ` [Patch V3 28/40] TigerlakeSiliconPkg/IpBlock: Add Smbus component Heng Luo
2021-02-05  7:40 ` [Patch V3 29/40] TigerlakeSiliconPkg/IpBlock: Add Spi component Heng Luo
2021-02-05  7:40 ` [Patch V3 30/40] TigerlakeSiliconPkg/IpBlock: Add Vtd component Heng Luo
2021-02-05  7:40 ` [Patch V3 31/40] TigerlakeSiliconPkg/Library: Add package common library instances Heng Luo
2021-02-05  7:40 ` [Patch V3 32/40] TigerlakeSiliconPkg/Pch: Add Pch " Heng Luo
2021-02-05  7:40 ` [Patch V3 33/40] TigerlakeSiliconPkg/Pch: Add Pch private " Heng Luo
2021-02-05  7:40 ` [Patch V3 34/40] TigerlakeSiliconPkg/SystemAgent: Add Acpi Tables and " Heng Luo
2021-02-05  7:40 ` [Patch V3 35/40] TigerlakeSiliconPkg/Fru/TglCpu: Add CpuPcieRp and Vtd " Heng Luo
2021-02-05  7:40 ` [Patch V3 36/40] TigerlakeSiliconPkg/Pch: Add Pch modules Heng Luo
2021-02-05  7:40 ` [Patch V3 37/40] TigerlakeSiliconPkg/SystemAgent: Add SystemAgent modules Heng Luo
2021-02-05  7:40 ` [Patch V3 38/40] TigerlakeSiliconPkg/Fru: Add Fru DSC files Heng Luo
2021-02-05  7:40 ` [Patch V3 39/40] TigerlakeSiliconPkg: Add package " Heng Luo
2021-02-05  7:40 ` [Patch V3 40/40] Maintainers.txt: Add TigerlakeSiliconPkg maintainers Heng Luo
2021-02-05 18:36   ` Nate DeSimone
2021-02-05 18:57     ` Chaganty, Rangasai V

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox