* [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